From: Steve Brokenshire Date: Tue, 20 Oct 2015 18:34:42 +0000 (+0100) Subject: Split carddav/carddav.cpp down into 8 files to make it manageable. X-Git-Tag: release-0.05~32 X-Git-Url: http://Server1/repobrowser/?p=xestiaab%2F.git;a=commitdiff_plain;h=911611528b36f56f7de9b6bf027b4c2a1a54df00 Split carddav/carddav.cpp down into 8 files to make it manageable. --- diff --git a/source/carddav/carddav-connect.cpp b/source/carddav/carddav-connect.cpp new file mode 100644 index 0000000..d759cde --- /dev/null +++ b/source/carddav/carddav-connect.cpp @@ -0,0 +1,273 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +bool CardDAV::Connect(){ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + // Try SSL first. + + + /* + char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; + //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); + + char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; + //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); + + char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; + //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); + + */ + + if (ServerSSL){ + + union { + struct curl_slist *certdata; + struct curl_certinfo *certinfo; + } ptr; + + ptr.certdata = NULL; + + // Setup two initial connections and attempt to get the certificate data. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + + conncode = (curl_easy_perform(conn)); + + // Check if the SSL certificate is valid or self-signed or some other + // error occured. + + if (conncode == CURLE_OK){ + + // Connection is OK. Do nothing. + + } else if (conncode == CURLE_SSL_CACERT){ + + // Post message saying SSL certificate is invalid. + + curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata); + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + return FALSE; + + } + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + + if (AllowSelfSign == TRUE){ + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); + } + + conncode = (curl_easy_perform(conn)); + + ptr.certdata = NULL; + + curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata); + + if (conncode == CURLE_OK){ + + // Process the server header response and look for + // 'addressbook' within the DAV header. + + wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); + wxString wxSHeaderLine; + std::map DAVHeaderLines; + + while (wxSHeaderLines.HasMoreTokens()){ + + wxSHeaderLine = wxSHeaderLines.GetNextToken(); + + if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ + + // Look for address book in the line. + + if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ + + HasCalDAVSupport = TRUE; + + } + + } + + } + + *ServerResult = TRUE; + ValidResponse = TRUE; + AuthPassed = TRUE; + SSLStatus = TRUE; + return TRUE; + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = TRUE; + ValidResponse = FALSE; + AuthPassed = FALSE; + SSLStatus = TRUE; + return TRUE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + return FALSE; + + } + + } else { + + // No SSL. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + // Process the server header response and look for + // 'addressbook' within the DAV header. + + wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); + wxString wxSHeaderLine; + std::map DAVHeaderLines; + + while (wxSHeaderLines.HasMoreTokens()){ + + wxSHeaderLine = wxSHeaderLines.GetNextToken(); + + if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ + + // Look for address book in the line. + + if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ + + HasCalDAVSupport = TRUE; + + } + + } + + } + + *ServerResult = TRUE; + ValidResponse = TRUE; + AuthPassed = TRUE; + SSLStatus = FALSE; + return TRUE; + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + *ServerResult = TRUE; + ValidResponse = FALSE; + AuthPassed = FALSE; + SSLStatus = FALSE; + return TRUE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + return FALSE; + + } + + // TODO: Double check and make sure HTTP Authentication is possible. + + } + + *ServerResult = TRUE; + return TRUE; + +} diff --git a/source/carddav/carddav-contactlist.cpp b/source/carddav/carddav-contactlist.cpp new file mode 100644 index 0000000..188e772 --- /dev/null +++ b/source/carddav/carddav-contactlist.cpp @@ -0,0 +1,929 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ + + ContactListData ContactListFinal; + std::map ContactList; + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/"); + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + // Load the sync token file (if it exists). + + wxCharBuffer SyncDataBuffer; + wxString SyncData; + + SyncData.Clear(); + + SyncTokenInc.Trim(); + + if (!SyncTokenInc.IsEmpty()){ + + SyncData = wxT("\n"); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("")); + //SyncData.Trim(); + //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580")); + SyncData.Append(SyncTokenInc); + //SyncData.Trim(); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("1\n")); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT(" \n")); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("")); + + SyncDataBuffer = SyncData.ToUTF8(); + + } else { + + SyncData = wxT("\n"); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("1\n")); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT(" \n")); + SyncData.Append(wxT("\n")); + SyncData.Append(wxT("\n")); + + SyncDataBuffer = SyncData.ToUTF8(); + + } + + //static const char* query = SyncData.mb_str(); + + /*char *query = "\n\ + \n\ + data:,00378c55-1f44-44a2-a255-84f6560b5cac_580\n\ + 1\n\ + \n\ + \n\ + \n\ + \n";*/ + const char* query = SyncDataBuffer.data(); + + // Try SSL first. + + std::map::iterator ActIter; + struct UploadDataStruc UploadData; + + ActIter = ActivityListPtr->find((int)ItemIndex); + + curl_slist *slist = NULL; + + slist = curl_slist_append(slist, "Depth: 1"); + + if (ServerSSL){ + + wxString ServerCertFilename; + bool MatchingCert = FALSE; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); + + if (wxFile::Exists(ServerCertFilename) == TRUE){ + + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); + + } + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + claconncode = (curl_easy_perform(conn)); + + // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without + // the local certificate in use. + + if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + claconncode = (curl_easy_perform(conn)); + + // If claconncode is CURLE_OK then delete the certificate file as that + // is no longer needed. + + if (claconncode == CURLE_OK){ + + // Delete the certificate file. + + wxRemoveFile(ServerCertFilename); + + } + + } + + // Check if it fails with a CURLE_SSL_CACERT then compare + // the certificates as PEM files. + + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ + + //curl_easy_cleanup(conn); + //conn = curl_easy_init(); + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + //claconncode = (curl_easy_perform(conn)); + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + wxString SSLLocalData; + wxString SSLServerData; + + 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")); + + wxFFile SSLLocalFile; + +#if wxABI_VERSION < 20900 + SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); +#else + SSLLocalFile.Open(ServerCertFilename, wxT("r")); +#endif + + // Load the recovery database for tasks not done. + + if (SSLLocalFile.IsOpened() == TRUE){ + + // Check if we are using wxWidgets version 2.8 or less and + // execute the required command accordingly. + + SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); + + + } + + SSLServerData = SSLDataIter->second; + + if (SSLLocalData == SSLServerData){ + + // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER + // and CURLOPT_SSL_VERIFYHOST off. + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + PageHeader.clear(); + PageData.clear(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); + + claconncode = (curl_easy_perform(conn)); + + MatchingCert = TRUE; + + } + + if (MatchingCert == FALSE){ + + claconncode = CURLE_SSL_CACERT; + return ContactListFinal; + + } + + curl_easy_cleanup(sslerrconn); + + } + + // Sort out SSL error. + + // When SSL cert error occurs, connect again and fetch certificates. + // Display a message to the user explaining that an invalid + // certificate has been given and let the user decide what + // to do next. + + if (claconncode == CURLE_OK){ + + } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + // Replace conn with sslerrconn! + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + sslerrconncode = (curl_easy_perform(sslerrconn)); + + SSLCertCol = BuildSSLCollection(sslerrconn); + SSLCertCol.SuccessCode = 1; + + return ContactListFinal; + + } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return ContactListFinal; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return ContactListFinal; + + } + + SSLCertCol = BuildSSLCollection(conn); + + } else { + + // No SSL. + + wxString EmptyString; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + PageData.Clear(); + PageHeader.Clear(); + + claconncode = (curl_easy_perform(conn)); + + if (claconncode == CURLE_OK){ + + + + } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %i\n", http_code); + + return ContactListFinal; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %i\n", http_code); + + return ContactListFinal; + + } + + } + + xmlDocPtr xmlCardDAVDoc; + xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); + + xmlNodePtr nodeLevel1; + xmlNodePtr nodeLevel2; + xmlNodePtr nodeLevel3; + xmlNodePtr nodeLevel4; + xmlNodePtr nodeLevel5; + xmlNodePtr nodeLevel6; + + xmlNodePtr nodeStatusLv1; + xmlNodePtr nodeStatusLv2; + + std::map xmlDataMap; + std::map ServerETagData; + + wxString DataFilename; + wxString DataSyncToken; + int DataFileStatus; + wxString ETagData; + bool SyncTokenFound = FALSE; + + std::string xmlStringSafe; + + // Tranverse through the catacombs of the response to get our ETag for the file and + // the server syncronisation token. + + // Start by getting all the server ETag data. + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + DataFileStatus = 0; + bool HREFFound = FALSE; + bool ETagFound = FALSE; + bool HTTPStatus = FALSE; + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") + ){ + + // Get the filename. + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") + ){ + + DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); + wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); + + while (wSTDFilename.HasMoreTokens()){ + + DataFilename = wSTDFilename.GetNextToken(); + + } + + HREFFound = TRUE; + + } + + + + } + + + } else { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeStatusLv1 = nodeLevel3->children; + nodeStatusLv1 != NULL; + nodeStatusLv1 = nodeStatusLv1->next) + { + + if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){ + + DataFileStatus = 2; + + HTTPStatus = TRUE; + + } + + if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") || + !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") || + !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE) + { + + // Get the filename. + + for (nodeStatusLv2 = nodeStatusLv1->children; + nodeStatusLv2 != NULL; + nodeStatusLv2 = nodeStatusLv2->next) + { + + if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text") + ){ + + if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){ + + DataFileStatus = 1; + + HTTPStatus = TRUE; + + // This is currently in a WebDAV draft and may hopefully be enabled when this changes. + + //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){ + + // DataFileStatus = 0; + + } + + } + + + + } + + } + + + } + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") + ){ + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + // Strip the quotes from the ETag. + + ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); + if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ + + ETagData.Remove(0, 1); + ETagData.RemoveLast(); + + } + + ETagFound = TRUE; + + } + + } + + } + + } + + } + + if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){ + + // Add to the map data. + + FileSyncData SData; + + SData.ETagData = ETagData; + SData.DataFlag = DataFileStatus; + + ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); + + } + + // Reset the values. + + HREFFound = FALSE; + ETagFound = FALSE; + HTTPStatus = FALSE; + + } + + if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") || + !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") || + !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) && + SyncTokenFound == FALSE + ){ + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text") + ){ + + DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content); + + SyncTokenFound = TRUE; + + } + + } + + } + + } + + } + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + DataFileStatus = 0; + bool HREFFound = FALSE; + bool ETagFound = FALSE; + bool HTTPStatus = FALSE; + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") + ){ + + // Get the filename. + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") + ){ + + DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); + wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); + + while (wSTDFilename.HasMoreTokens()){ + + DataFilename = wSTDFilename.GetNextToken(); + + } + + HREFFound = TRUE; + + } + + + + } + + + } else { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeStatusLv1 = nodeLevel3->children; + nodeStatusLv1 != NULL; + nodeStatusLv1 = nodeStatusLv1->next) + { + + if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){ + + DataFileStatus = 2; + + HTTPStatus = TRUE; + + } + + if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") || + !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") || + !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE) + { + + // Get the filename. + + for (nodeStatusLv2 = nodeStatusLv1->children; + nodeStatusLv2 != NULL; + nodeStatusLv2 = nodeStatusLv2->next) + { + + if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text") + ){ + + if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){ + + DataFileStatus = 1; + + HTTPStatus = TRUE; + + // This is currently in a WebDAV draft and may hopefully be enabled when this changes. + + //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){ + + // DataFileStatus = 0; + + } + + } + + + + } + + } + + + } + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") + ){ + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + // Strip the quotes from the ETag. + + ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); + if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ + + ETagData.Remove(0, 1); + ETagData.RemoveLast(); + + } + + ETagFound = TRUE; + + } + + } + + } + + } + + } + + } + + if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){ + + FileSyncData SData; + + SData.ETagData = wxT(""); + SData.DataFlag = DataFileStatus; + + ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); + + } + + if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){ + + // Add to the map data. + + FileSyncData SData; + + SData.ETagData = ETagData; + SData.DataFlag = DataFileStatus; + + ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); + + } + + // Reset the values. + + HREFFound = FALSE; + ETagFound = FALSE; + HTTPStatus = FALSE; + DataFilename.Clear(); + + if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") || + !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") || + !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) && + SyncTokenFound == FALSE + ){ + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text") + ){ + + DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content); + + SyncTokenFound = TRUE; + + } + + } + + } + + } + + } + + // Get the sync token. + + if (SyncTokenFound == TRUE){ + + ContactListFinal.SyncToken = DataSyncToken; + + } else { + + } + + SleepFor(2000000000); + + /*timespec n1, n2; + + n1.tv_sec = 0; + n1.tv_nsec = 2000000000L; + + nanosleep(&n1, &n2);*/ + + xmlFreeDoc(xmlCardDAVDoc); + curl_easy_cleanup(conn); + + SyncDataBuffer.reset(); + + // Get the first result. + + return ContactListFinal; + +} \ No newline at end of file diff --git a/source/carddav/carddav-defaultadrurl.cpp b/source/carddav/carddav-defaultadrurl.cpp new file mode 100644 index 0000000..f258d69 --- /dev/null +++ b/source/carddav/carddav-defaultadrurl.cpp @@ -0,0 +1,663 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +wxString CardDAV::GetDefaultAddressBookURL(){ + + // First: Get the principal UID address. + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct curl_slist *connhd = NULL; + struct curl_slist *connhd2 = NULL; + struct curl_slist *connhd3 = NULL; + + connhd = curl_slist_append(connhd, "Depth: 0"); + connhd = curl_slist_append(connhd, "Prefer: return-minimal"); + connhd = curl_slist_append(connhd, "Content-Type: application/xml; charset=utf-8"); + + connhd2 = curl_slist_append(connhd2, "Depth: 0"); + connhd2 = curl_slist_append(connhd2, "Prefer: return-minimal"); + connhd2 = curl_slist_append(connhd2, "Content-Type: application/xml; charset=utf-8"); + + connhd3 = curl_slist_append(connhd3, "Depth: 1"); + connhd3 = curl_slist_append(connhd3, "Prefer: return-minimal"); + connhd3 = curl_slist_append(connhd3, "Content-Type: application/xml; charset=utf-8"); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + wxString ETag; + wxString ETagOriginal; + wxString ETagServer; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + wxString SAURLPrincipals; + wxString SAURLPrincipalURL; + wxString SAURLAddressURL; + + if (ServerSSL){ + + SAURLPrincipals = ServerAddressSSL + wxT("principals/"); + SAURLPrincipalURL = ServerAddressSSL; + SAURLAddressURL = ServerAddressSSL; + + } else { + + SAURLPrincipals = ServerAddressNormal + wxT("principals/"); + SAURLPrincipalURL = ServerAddressNormal; + SAURLAddressURL = ServerAddressNormal; + + } + + wxString FinalPrefix; + + struct UploadDataStruc UploadData; + + // Setup the first query finding out where the principal URL is. + + const char* query = "\n" + "\n" + " " + " \n" + " " + ""; + + // Setup the second query finding out where the address book home URL is. + + const char* query2 = "\n" + "\n" + " \n" + " \n" + " \n" + ""; + + // Setup the third query finding out where the default address book URL is. + + const char* query3 = "\n" + "\n" + " \n" + " \n" + " \n" + ""; + + if (ServerSSL){ + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd); + + if (AllowSelfSign == TRUE){ + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); + } + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + *ServerResult = TRUE; + AuthPassed = TRUE; + ValidResponse = TRUE; + SSLStatus = TRUE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + return wxT(""); + + } + + } else { + + // No SSL. + + // Do an initial connection (incase of Digest authentication). + + PageData.Clear(); + PageHeader.Clear(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd); + + conncode = (curl_easy_perform(conn)); + + // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, + // then bring up the conflict resolution form. + + if (EditMode == TRUE){ + + } + + if (conncode == CURLE_OK){ + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", + GetHTTPCode()); + + return wxT(""); + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + return wxT(""); + + } + + } + + // Process the XML data from the application. + + xmlDocPtr xmlCardDAVDoc; + xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); + + xmlNodePtr nodeLevel1; + xmlNodePtr nodeLevel2; + xmlNodePtr nodeLevel3; + xmlNodePtr nodeLevel4; + xmlNodePtr nodeLevel5; + xmlNodePtr nodeLevel6; + xmlNodePtr nodeLevel7; + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") + ){ + + // Found the part so extract the principal URL address. + + for (nodeLevel7 = nodeLevel6->children; + nodeLevel7 != NULL; + nodeLevel7 = nodeLevel7->next) + { + + SAURLPrincipalURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content)); + + } + + } + + } + + } + + } + + } + + } + + } + + xmlFreeDoc(xmlCardDAVDoc); + PageData.Clear(); + PageHeader.Clear(); + + // Second: Get the addressbook-home-set + + curl_easy_reset(conn); + + if (ServerSSL){ + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2); + + if (AllowSelfSign == TRUE){ + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); + } + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + *ServerResult = TRUE; + AuthPassed = TRUE; + SSLStatus = TRUE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + ValidResponse = FALSE; + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + return wxT(""); + + } + + } else { + + // No SSL. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2); + + conncode = (curl_easy_perform(conn)); + + // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, + // then bring up the conflict resolution form. + + if (EditMode == TRUE){ + + } + + if (conncode == CURLE_OK){ + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", + GetHTTPCode()); + + ValidResponse = FALSE; + + return wxT(""); + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ValidResponse = FALSE; + + return wxT(""); + + } + + } + + xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") + ){ + + // Found the part so extract the principal URL address. + + for (nodeLevel7 = nodeLevel6->children; + nodeLevel7 != NULL; + nodeLevel7 = nodeLevel7->next) + { + + SAURLAddressURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content)); + + } + + } + + } + + } + + } + + } + + } + + } + + xmlFreeDoc(xmlCardDAVDoc); + PageData.Clear(); + PageHeader.Clear(); + + // Finally: Get the default-addressbook-URL from the addressbook-home-set address. + + curl_easy_reset(conn); + + if (ServerSSL){ + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3); + + if (AllowSelfSign == TRUE){ + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); + } + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + *ServerResult = TRUE; + AuthPassed = TRUE; + SSLStatus = TRUE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + ValidResponse = FALSE; + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + return wxT(""); + + } + + } else { + + // No SSL. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3)); + curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3); + + conncode = (curl_easy_perform(conn)); + + // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, + // then bring up the conflict resolution form. + + if (EditMode == TRUE){ + + } + + if (conncode == CURLE_OK){ + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", + GetHTTPCode()); + + ValidResponse = FALSE; + + return wxT(""); + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ValidResponse = FALSE; + + return wxT(""); + + } + + } + + xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") + ){ + + // Found the part so extract the principal URL address. + + for (nodeLevel7 = nodeLevel6->children; + nodeLevel7 != NULL; + nodeLevel7 = nodeLevel7->next) + { + + FinalPrefix = wxString::FromUTF8((const char*)nodeLevel7->content); + + } + + } + + } + + } + + } + + } + + } + + } + + xmlFreeDoc(xmlCardDAVDoc); + PageData.Clear(); + PageHeader.Clear(); + + return FinalPrefix; + +} diff --git a/source/carddav/carddav-processdata.cpp b/source/carddav/carddav-processdata.cpp new file mode 100644 index 0000000..f3bfdae --- /dev/null +++ b/source/carddav/carddav-processdata.cpp @@ -0,0 +1,502 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +void CardDAV::ProcessDataThread(){ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + wxString ETag; + wxString ETagOriginal; + wxString ETagServer; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + // Try SSL first. + + + /* + char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; + //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); + + char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; + //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); + + char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; + //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); + + */ + + //std::string WriteDataString = std::string(ServerUploadData.mb_str()); + + std::map::iterator ActIter; + struct UploadDataStruc UploadData; + + + ActIter = ActivityListPtr->find((int)ItemIndex); + + // Update result flag. + + ActIter->second = 1; + + // Setup the request mode if it is not empty. + + if (!ServerMethod.IsEmpty()){ + + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8)); + + } + + if (ServerSSL){ + + wxString ServerCertFilename; + bool MatchingCert = FALSE; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + if (UploadMode == TRUE){ + + UploadData.readptr = &ServerUploadData; + UploadData.sizeleft = ServerUploadData.Len(); + curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + } + + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); + + if (wxFile::Exists(ServerCertFilename) == TRUE){ + + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); + + } + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + + claconncode = (curl_easy_perform(conn)); + + // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without + // the local certificate in use. + + if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + if (UploadMode == TRUE){ + + UploadData.readptr = &ServerUploadData; + UploadData.sizeleft = ServerUploadData.Len(); + curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + } + + claconncode = (curl_easy_perform(conn)); + + // If claconncode is CURLE_OK then delete the certificate file as that + // is no longer needed. + + if (claconncode == CURLE_OK){ + + // Delete the certificate file. + + wxRemoveFile(ServerCertFilename); + + } + + } + + // Check if it fails with a CURLE_SSL_CACERT then compare + // the certificates as PEM files. + + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ + + //curl_easy_cleanup(conn); + //conn = curl_easy_init(); + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + //claconncode = (curl_easy_perform(conn)); + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + wxString SSLLocalData; + wxString SSLServerData; + + 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")); + + wxFFile SSLLocalFile; + +#if wxABI_VERSION < 20900 + SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); +#else + SSLLocalFile.Open(ServerCertFilename, wxT("r")); +#endif + + // Load the recovery database for tasks not done. + + if (SSLLocalFile.IsOpened() == TRUE){ + + // Check if we are using wxWidgets version 2.8 or less and + // execute the required command accordingly. + + SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); + + + } + + SSLServerData = SSLDataIter->second; + + if (SSLLocalData == SSLServerData){ + + // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER + // and CURLOPT_SSL_VERIFYHOST off. + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + PageData.clear(); + PageHeader.clear(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + if (UploadMode == TRUE){ + + UploadData.readptr = &ServerUploadData; + UploadData.sizeleft = ServerUploadData.Len(); + curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + } + + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); + + claconncode = (curl_easy_perform(conn)); + + MatchingCert = TRUE; + + } + + if (MatchingCert == FALSE){ + + claconncode = CURLE_SSL_CACERT; + return; + + } + + curl_easy_cleanup(sslerrconn); + + } + + // Sort out SSL error. + + // When SSL cert error occurs, connect again and fetch certificates. + // Display a message to the user explaining that an invalid + // certificate has been given and let the user decide what + // to do next. + + if (claconncode == CURLE_OK){ + + } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + // Replace conn with sslerrconn! + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + sslerrconncode = (curl_easy_perform(sslerrconn)); + + SSLCertCol = BuildSSLCollection(sslerrconn); + SSLCertCol.SuccessCode = 1; + + return; + + } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return; + + } + + } else { + + // No SSL. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + if (UploadMode == TRUE){ + + UploadData.readptr = &ServerUploadData; + UploadData.sizeleft = ServerUploadData.Len(); + curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + } + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + // Process the server header response and look for + // 'addressbook' within the DAV header. + + wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); + wxString wxSHeaderLine; + std::map DAVHeaderLines; + + while (wxSHeaderLines.HasMoreTokens()){ + + wxSHeaderLine = wxSHeaderLines.GetNextToken(); + + if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){ + + ETagData = wxSHeaderLine.Mid(5); + ETagData.Trim(); + ETagData.Trim(FALSE); + + // Check for commas. + + if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ + + ETagData.Remove(0, 1); + ETagData.RemoveLast(); + + } + + } + + if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ + + // Look for address book in the line. + + if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ + + HasCalDAVSupport = TRUE; + + } + + } + + } + + // Get the ETag from the header. + + if (UploadMode == TRUE){ + + wxString PageHeaderLine; + + wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n")); + + if (PageHeaderSplit.HasMoreTokens()){ + + PageHeaderLine = PageHeaderSplit.GetNextToken(); + + } + + } + + ActIter->second = 4; + return; + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", + GetHTTPCode()); + + ActIter->second = 2; + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ActIter->second = 2; + return; + + } + + } + + // Catch all. + + //ActIter->second = 1; + *ServerResult = TRUE; + return; + +} + +void CardDAV::ProcessData(){ + + std::thread ConnectThread(&CardDAV::ProcessDataThread, this); + ConnectThread.detach(); + +} \ No newline at end of file diff --git a/source/carddav/carddav-servercontact.cpp b/source/carddav/carddav-servercontact.cpp new file mode 100644 index 0000000..3c94d88 --- /dev/null +++ b/source/carddav/carddav-servercontact.cpp @@ -0,0 +1,396 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +void CardDAV::GetServerContactData() +{ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + wxString ServerCertFilename; + bool MatchingCert = FALSE; + + CURL *conn; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + // Try SSL first. + + + /* + char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; + //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); + + char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; + //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); + + char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; + //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); + + */ + + //std::string WriteDataString = std::string(ServerUploadData.mb_str()); + + std::map::iterator ActIter; + struct UploadDataStruc UploadData; + + + ActIter = ActivityListPtr->find((int)ItemIndex); + + //ActIter->second = 1; + + /*wxString CardDAVDataQuery = wxT("\r\n"); + CardDAVDataQuery.Append(wxT("\r\n")); + CardDAVDataQuery.Append(wxT("\r\n")); + CardDAVDataQuery.Append(wxT("\r\n")); + CardDAVDataQuery.Append(wxT(" \r\n")); + CardDAVDataQuery.Append(wxT("\r\n")); + CardDAVDataQuery.Append(wxT(""));*/ + + if (ServerSSL){ + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); + + if (wxFile::Exists(ServerCertFilename) == TRUE){ + + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); + + } + + claconncode = (curl_easy_perform(conn)); + + // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without + // the local certificate in use. + + if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + + claconncode = (curl_easy_perform(conn)); + + // If claconncode is CURLE_OK then delete the certificate file as that + // is no longer needed. + + if (claconncode == CURLE_OK){ + + // Delete the certificate file. + + wxRemoveFile(ServerCertFilename); + + } + + } + + // Check if it fails with a CURLE_SSL_CACERT then compare + // the certificates as PEM files. + + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ + + //curl_easy_cleanup(conn); + //conn = curl_easy_init(); + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + //claconncode = (curl_easy_perform(conn)); + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + wxString SSLLocalData; + wxString SSLServerData; + + 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")); + + wxFFile SSLLocalFile; + +#if wxABI_VERSION < 20900 + SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); +#else + SSLLocalFile.Open(ServerCertFilename, wxT("r")); +#endif + + // Load the recovery database for tasks not done. + + if (SSLLocalFile.IsOpened() == TRUE){ + + SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); + + + } + + SSLServerData = SSLDataIter->second; + + if (SSLLocalData == SSLServerData){ + + // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER + // and CURLOPT_SSL_VERIFYHOST off. + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + PageData.clear(); + PageHeader.clear(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); + + claconncode = (curl_easy_perform(conn)); + + MatchingCert = TRUE; + + } + + if (MatchingCert == FALSE){ + + claconncode = CURLE_SSL_CACERT; + return; + + } + + curl_easy_cleanup(sslerrconn); + + } + + // Sort out SSL error. + + // When SSL cert error occurs, connect again and fetch certificates. + // Display a message to the user explaining that an invalid + // certificate has been given and let the user decide what + // to do next. + + if (claconncode == CURLE_OK){ + + } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + // Replace conn with sslerrconn! + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + sslerrconncode = (curl_easy_perform(sslerrconn)); + + SSLCertCol = BuildSSLCollection(sslerrconn); + SSLCertCol.SuccessCode = 1; + + return; + + } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + return; + + } + + } else { + + // No SSL. + + wxString EmptyString; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + + PageData.Clear(); + PageHeader.Clear(); + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", + GetHTTPCode()); + + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + return; + + } + + } + + return; + +} \ No newline at end of file diff --git a/source/carddav/carddav-serveretag.cpp b/source/carddav/carddav-serveretag.cpp new file mode 100644 index 0000000..85b0e15 --- /dev/null +++ b/source/carddav/carddav-serveretag.cpp @@ -0,0 +1,585 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +void CardDAV::GetServerETagValueThread() +{ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + bool FilenameIsDirectory = FALSE; + CURL *conn; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE; + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; + ServerAddressSSL = wxT("https://") + ServerAddressURL; + ServerAddressNormal = wxT("http://") + ServerAddressURL; + + ServerAuth = ServerUser + wxT(":") + ServerPass; + + // Workout if path is directory or filename. + + /*if (ServerAddress){ + FilenameIsDirectory = TRUE; + } else { + FilenameIsDirectory = FALSE; + }*/ + + // Try SSL first. + + + /* + char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; + //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); + + char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; + //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); + + char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; + //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); + strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); + + */ + + //std::string WriteDataString = std::string(ServerUploadData.mb_str()); + + std::map::iterator ActIter; + struct UploadDataStruc UploadData; + + + ActIter = ActivityListPtr->find((int)ItemIndex); + + static const char* query = + "" + "" + "" + //"" + //" " + //"" + "" + "" + ""; + + if (ServerSSL){ + + wxString ServerCertFilename; + bool MatchingCert = FALSE; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); + + if (wxFile::Exists(ServerCertFilename) == TRUE){ + + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); + + } + + claconncode = (curl_easy_perform(conn)); + + // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without + // the local certificate in use. + + if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + claconncode = (curl_easy_perform(conn)); + + // If claconncode is CURLE_OK then delete the certificate file as that + // is no longer needed. + + if (claconncode == CURLE_OK){ + + // Delete the certificate file. + + wxRemoveFile(ServerCertFilename); + + } + + } + + // Check if it fails with a CURLE_SSL_CACERT then compare + // the certificates as PEM files. + + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ + + //curl_easy_cleanup(conn); + //conn = curl_easy_init(); + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + //claconncode = (curl_easy_perform(conn)); + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + PageData.clear(); + PageHeader.clear(); + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); + + wxString SSLLocalData; + wxString SSLServerData; + + 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")); + + wxFFile SSLLocalFile; + +#if wxABI_VERSION < 20900 + SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); +#else + SSLLocalFile.Open(ServerCertFilename, wxT("r")); +#endif + + // Load the recovery database for tasks not done. + + if (SSLLocalFile.IsOpened() == TRUE){ + + // Check if we are using wxWidgets version 2.8 or less and + // execute the required command accordingly. + + SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); + + + } + + SSLServerData = SSLDataIter->second; + + if (SSLLocalData == SSLServerData){ + + // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER + // and CURLOPT_SSL_VERIFYHOST off. + + curl_easy_cleanup(conn); + conn = curl_easy_init(); + + PageData.clear(); + PageHeader.clear(); + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); + + claconncode = (curl_easy_perform(conn)); + + MatchingCert = TRUE; + + } + + if (MatchingCert == FALSE){ + + claconncode = CURLE_SSL_CACERT; + return; + + } + + curl_easy_cleanup(sslerrconn); + + } + + // Sort out SSL error. + + // When SSL cert error occurs, connect again and fetch certificates. + // Display a message to the user explaining that an invalid + // certificate has been given and let the user decide what + // to do next. + + if (claconncode == CURLE_OK){ + + } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ + + CURL *sslerrconn; + sslerrconn = curl_easy_init(); + CURLcode sslerrconncode; + + wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + + // Replace conn with sslerrconn! + + curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); + curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); + + sslerrconncode = (curl_easy_perform(sslerrconn)); + + SSLCertCol = BuildSSLCollection(sslerrconn); + SSLCertCol.SuccessCode = 1; + + curl_easy_cleanup(conn); + curl_easy_cleanup(sslerrconn); + + return; + + } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + curl_easy_cleanup(conn); + + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(claconncode)); + int http_code = 0; + curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); + fprintf(stderr, "Error code was: %d\n", http_code); + + curl_easy_cleanup(conn); + + return; + + } + + } else { + + // No SSL. + + wxString EmptyString; + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); + curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); + curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); + curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); + curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); + + //UploadData.readptr = &CardDAVDataQuery; + //UploadData.sizeleft = CardDAVDataQuery.Len(); + //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); + //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); + //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); + + //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); + curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); + + PageData.Clear(); + PageHeader.Clear(); + + conncode = (curl_easy_perform(conn)); + + if (conncode == CURLE_OK){ + + } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + return; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + return; + + } + + } + + xmlDocPtr xmlCardDAVDoc; + + xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); + + xmlNodePtr nodeLevel1; + xmlNodePtr nodeLevel2; + xmlNodePtr nodeLevel3; + xmlNodePtr nodeLevel4; + xmlNodePtr nodeLevel5; + xmlNodePtr nodeLevel6; + + std::map xmlDataMap; + + wxString DataFilename; + wxString ETagData; + + std::string xmlStringSafe; + + // Tranverse through the catacombs of the response to get our ETag for the file. + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + bool HREFFound = FALSE; + bool ETagFound = FALSE; + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") + ){ + + // Get the filename. + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") + ){ + + DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); + wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); + + while (wSTDFilename.HasMoreTokens()){ + + DataFilename = wSTDFilename.GetNextToken(); + + } + + HREFFound = TRUE; + + } + + + + } + + } else { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") + ){ + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + // Strip the quotes from the ETag. + + ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); + if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ + + ETagData.Remove(0, 1); + ETagData.RemoveLast(); + + } + + ETagFound = TRUE; + + } + + } + + } + + } + + } + + } + + } + + if (HREFFound == TRUE && ETagFound == TRUE){ + + // Add to the map data. + + xmlDataMap.insert(std::make_pair(DataFilename, ETagData)); + + HREFFound = FALSE; + ETagFound = FALSE; + + } + + + } + + xmlFreeDoc(xmlCardDAVDoc); + + // Get the first result. + + for (std::map::iterator iter = xmlDataMap.begin(); + iter != xmlDataMap.end(); ++iter){ + + ETagResult = iter->second; + break; + + } + + if (ETagResult.IsEmpty()){ + + return; + + } + + return; + +} + +void CardDAV::GetServerETagValue(){ + + std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this); + ConnectThread.detach(); + +} \ No newline at end of file diff --git a/source/carddav/carddav-sslverify.cpp b/source/carddav/carddav-sslverify.cpp new file mode 100644 index 0000000..89998de --- /dev/null +++ b/source/carddav/carddav-sslverify.cpp @@ -0,0 +1,136 @@ +#include "carddav.h" +#include "../version.h" +#include +#include +#include +#include +#include +#include +#include +#include "../vcard/vcard.h" +#include "../common/dirs.h" + +CURLcode CardDAV::SSLVerifyTest(){ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + CURL *connssldata; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + /*struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE;*/ + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + ServerAddressSSL = wxT("https://") + ServerAddressURL; + + if (ServerSSL){ + + union { + struct curl_slist *certdata; + struct curl_certinfo *certinfo; + } ptr; + + ptr.certdata = NULL; + + // Setup two initial connections and attempt to get the certificate data. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + + conncode = (curl_easy_perform(conn)); + + // Check if the SSL certificate is valid or self-signed or some other + // error occured. + + if (conncode == CURLE_OK){ + + // Connection is OK. Do nothing. + + *ServerResult = TRUE; + + } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){ + + connssldata = curl_easy_init(); + + // Retry but get the certificates without peer/host verification. + + curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1); + curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer); + curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader); + curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L); + + CURLcode certfetchcode; + + certfetchcode = (curl_easy_perform(connssldata)); + + VerifyCertCollection = BuildSSLCollection(connssldata); + + if (certfetchcode == CURLE_OK){ + + curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata); + + VerifyCertCollection = BuildSSLCollection(connssldata); + + } else { + + conncode = certfetchcode; + + } + + *ServerResult = FALSE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + + } + + } + + curl_easy_cleanup(conn); + + return conncode; + +} \ No newline at end of file diff --git a/source/carddav/carddav.cpp b/source/carddav/carddav.cpp index 33710f8..29f1c70 100644 --- a/source/carddav/carddav.cpp +++ b/source/carddav/carddav.cpp @@ -21,12 +21,6 @@ size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){ } -struct UploadDataStruc{ - wxString *readptr; - long sizeleft; - int seek = 0; -}; - int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){ int ProgressRet; @@ -233,131 +227,6 @@ void CardDAV::Abort(){ } -CURLcode CardDAV::SSLVerifyTest(){ - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - CURL *conn; - CURL *connssldata; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - /*struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE;*/ - - wxString Data1; - wxString Data2; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - ServerAddressSSL = wxT("https://") + ServerAddressURL; - - if (ServerSSL){ - - union { - struct curl_slist *certdata; - struct curl_certinfo *certinfo; - } ptr; - - ptr.certdata = NULL; - - // Setup two initial connections and attempt to get the certificate data. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L); - //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE); - //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE); - curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - - conncode = (curl_easy_perform(conn)); - - // Check if the SSL certificate is valid or self-signed or some other - // error occured. - - if (conncode == CURLE_OK){ - - // Connection is OK. Do nothing. - - *ServerResult = TRUE; - - } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){ - - connssldata = curl_easy_init(); - - // Retry but get the certificates without peer/host verification. - - curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1); - curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer); - curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L); - - CURLcode certfetchcode; - - certfetchcode = (curl_easy_perform(connssldata)); - - VerifyCertCollection = BuildSSLCollection(connssldata); - - if (certfetchcode == CURLE_OK){ - - curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata); - - VerifyCertCollection = BuildSSLCollection(connssldata); - - } else { - - conncode = certfetchcode; - - } - - *ServerResult = FALSE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - - } - - } - - curl_easy_cleanup(conn); - - return conncode; - -} - SSLCertCollection CardDAV::GetSSLVerifyResults(){ return VerifyCertCollection; } @@ -366,3445 +235,95 @@ void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){ AllowSelfSign = AllowSelfSignIn; } -bool CardDAV::Connect(){ - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - CURL *conn; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - // Try SSL first. - - - /* - char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; - //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); - - char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; - //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); - - char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; - //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); - - */ - - if (ServerSSL){ - - union { - struct curl_slist *certdata; - struct curl_certinfo *certinfo; - } ptr; - - ptr.certdata = NULL; - - // Setup two initial connections and attempt to get the certificate data. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - - conncode = (curl_easy_perform(conn)); - - // Check if the SSL certificate is valid or self-signed or some other - // error occured. - - if (conncode == CURLE_OK){ - - // Connection is OK. Do nothing. - - } else if (conncode == CURLE_SSL_CACERT){ - - // Post message saying SSL certificate is invalid. - - curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata); - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - return FALSE; - - } - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - - if (AllowSelfSign == TRUE){ - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); - } - - conncode = (curl_easy_perform(conn)); - - ptr.certdata = NULL; - - curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata); - - if (conncode == CURLE_OK){ - - // Process the server header response and look for - // 'addressbook' within the DAV header. - - wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); - wxString wxSHeaderLine; - std::map DAVHeaderLines; - - while (wxSHeaderLines.HasMoreTokens()){ - - wxSHeaderLine = wxSHeaderLines.GetNextToken(); - - if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ - - // Look for address book in the line. - - if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ - - HasCalDAVSupport = TRUE; - - } - - } - - } - - *ServerResult = TRUE; - ValidResponse = TRUE; - AuthPassed = TRUE; - SSLStatus = TRUE; - return TRUE; - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); - - *ServerResult = TRUE; - ValidResponse = FALSE; - AuthPassed = FALSE; - SSLStatus = TRUE; - return TRUE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - return FALSE; - - } +void CardDAV::GetSSLResults(){ - } else { - // No SSL. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - // Process the server header response and look for - // 'addressbook' within the DAV header. - - wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); - wxString wxSHeaderLine; - std::map DAVHeaderLines; - - while (wxSHeaderLines.HasMoreTokens()){ - - wxSHeaderLine = wxSHeaderLines.GetNextToken(); - - if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ - - // Look for address book in the line. - - if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ - - HasCalDAVSupport = TRUE; - - } - - } - - } - - *ServerResult = TRUE; - ValidResponse = TRUE; - AuthPassed = TRUE; - SSLStatus = FALSE; - return TRUE; - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = TRUE; - ValidResponse = FALSE; - AuthPassed = FALSE; - SSLStatus = FALSE; - return TRUE; - - } else { +} - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - return FALSE; +void CardDAV::SetServerFilename(wxString Filename){ - } - - // TODO: Double check and make sure HTTP Authentication is possible. - - } - - *ServerResult = TRUE; - return TRUE; + ServerFilenameLocation = Filename; } -void CardDAV::GetSSLResults(){ +wxString CardDAV::GetPageData() +{ - + return PageData; } -void CardDAV::ProcessDataThread(){ +wxString CardDAV::ETagValueResult(){ - PageData.Clear(); - PageHeader.Clear(); + return ETagResult; - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; +} - CURL *conn; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; +void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){ - conn = curl_easy_init(); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; + ServerMethod = Method; + ServerFilenameLocation = FilenameLocation; + ServerUploadData = UploadData; - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; + // Check if ServerFilenameLocation has a / at + // the start and if not then append it. - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; + if (ServerFilenameLocation.Left(1) != wxT("/")){ - wxString ETag; - wxString ETagOriginal; - wxString ETagServer; + // Not there so insert. - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - // Try SSL first. - - - /* - char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; - //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); + ServerFilenameLocation = wxT("/") + ServerFilenameLocation; - char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; - //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); + } - char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; - //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); - - */ +} - //std::string WriteDataString = std::string(ServerUploadData.mb_str()); +void CardDAV::SetupVariables(std::map *actlist, int actindex){ - std::map::iterator ActIter; - struct UploadDataStruc UploadData; - - - ActIter = ActivityListPtr->find((int)ItemIndex); - - // Update result flag. + ActivityListPtr = actlist; + ItemIndex = actindex; - ActIter->second = 1; - - // Setup the request mode if it is not empty. - - if (!ServerMethod.IsEmpty()){ - - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8)); +} - } +wxString CardDAV::GetETagData(){ - if (ServerSSL){ - - wxString ServerCertFilename; - bool MatchingCert = FALSE; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - if (UploadMode == TRUE){ - - UploadData.readptr = &ServerUploadData; - UploadData.sizeleft = ServerUploadData.Len(); - curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - } + return ETagData; - ServerCertFilename = GetAccountDir(ServerAccount, TRUE); +} - if (wxFile::Exists(ServerCertFilename) == TRUE){ - - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); - - } +void CardDAV::SetUploadMode(bool IncMode){ - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - - claconncode = (curl_easy_perform(conn)); + UploadMode = IncMode; - // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without - // the local certificate in use. +} - if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - if (UploadMode == TRUE){ - - UploadData.readptr = &ServerUploadData; - UploadData.sizeleft = ServerUploadData.Len(); - curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - } - - claconncode = (curl_easy_perform(conn)); - - // If claconncode is CURLE_OK then delete the certificate file as that - // is no longer needed. - - if (claconncode == CURLE_OK){ - - // Delete the certificate file. - - wxRemoveFile(ServerCertFilename); - - } - - } +void CardDAV::SetEditMode(bool EditModeInc){ - // Check if it fails with a CURLE_SSL_CACERT then compare - // the certificates as PEM files. - - if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ - - //curl_easy_cleanup(conn); - //conn = curl_easy_init(); - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - //claconncode = (curl_easy_perform(conn)); - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - wxString SSLLocalData; - wxString SSLServerData; - - 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")); - - wxFFile SSLLocalFile; - -#if wxABI_VERSION < 20900 - SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); -#else - SSLLocalFile.Open(ServerCertFilename, wxT("r")); -#endif - - // Load the recovery database for tasks not done. - - if (SSLLocalFile.IsOpened() == TRUE){ + EditMode = EditModeInc; - // Check if we are using wxWidgets version 2.8 or less and - // execute the required command accordingly. - - SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); - - - } - - SSLServerData = SSLDataIter->second; - - if (SSLLocalData == SSLServerData){ - - // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER - // and CURLOPT_SSL_VERIFYHOST off. - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - PageData.clear(); - PageHeader.clear(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - if (UploadMode == TRUE){ - - UploadData.readptr = &ServerUploadData; - UploadData.sizeleft = ServerUploadData.Len(); - curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - } - - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); - - claconncode = (curl_easy_perform(conn)); - - MatchingCert = TRUE; - - } - - if (MatchingCert == FALSE){ - - claconncode = CURLE_SSL_CACERT; - return; - - } - - curl_easy_cleanup(sslerrconn); - - } +} - // Sort out SSL error. - - // When SSL cert error occurs, connect again and fetch certificates. - // Display a message to the user explaining that an invalid - // certificate has been given and let the user decide what - // to do next. +int CardDAV::GetResultCode(){ - if (claconncode == CURLE_OK){ + return (int)claconncode; - } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - // Replace conn with sslerrconn! - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - sslerrconncode = (curl_easy_perform(sslerrconn)); +} - SSLCertCol = BuildSSLCollection(sslerrconn); - SSLCertCol.SuccessCode = 1; +int CardDAV::GetHTTPCode(){ - return; - - } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - return; - - } else { + return HTTPErrorCode; - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); +} - return; +wxString CardDAV::GetErrorBuffer(){ - } - - } else { - - // No SSL. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - if (UploadMode == TRUE){ - - UploadData.readptr = &ServerUploadData; - UploadData.sizeleft = ServerUploadData.Len(); - curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - } - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - // Process the server header response and look for - // 'addressbook' within the DAV header. - - wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); - wxString wxSHeaderLine; - std::map DAVHeaderLines; - - while (wxSHeaderLines.HasMoreTokens()){ - - wxSHeaderLine = wxSHeaderLines.GetNextToken(); - - if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){ - - ETagData = wxSHeaderLine.Mid(5); - ETagData.Trim(); - ETagData.Trim(FALSE); - - // Check for commas. - - if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ - - ETagData.Remove(0, 1); - ETagData.RemoveLast(); - - } - - } - - if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ - - // Look for address book in the line. - - if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ - - HasCalDAVSupport = TRUE; - - } - - } - - } - - // Get the ETag from the header. - - if (UploadMode == TRUE){ - - wxString PageHeaderLine; - - wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n")); - - if (PageHeaderSplit.HasMoreTokens()){ - - PageHeaderLine = PageHeaderSplit.GetNextToken(); - - } - - } - - ActIter->second = 4; - return; - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", - GetHTTPCode()); - - ActIter->second = 2; - return; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ActIter->second = 2; - return; - - } - - } - - /* - - } - - */ - - // Connection was successful - /* - - if (conn){ - - wxString ServerAddressURL; - - // Try secure connection first. - - - - - ServerAddressURL = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - ServerAddressURL.Trim(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressURL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, NULL); - - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - *ServerResult = TRUE; - return TRUE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - return FALSE; - } - - // Failed. So use unsecure connection. - UseSSL = FALSE; - - ServerAddress = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort); - - curl_easy_setopt(conn, CURLOPT_URL, ServerAddress.c_str()); - - conncode = (curl_easy_perform(conn)); - - if (conncode != CURLE_OK){ - *ServerResult = FALSE; - return FALSE; - } else { - *ServerResult = TRUE; - return TRUE; - } - - } else { - - *ServerResult = FALSE; - return FALSE; - - } - - */ - - // Catch all. - - //ActIter->second = 1; - *ServerResult = TRUE; - return; - -} - -void CardDAV::ProcessData(){ - - std::thread ConnectThread(&CardDAV::ProcessDataThread, this); - ConnectThread.detach(); - -} - -void CardDAV::SetServerFilename(wxString Filename){ - - ServerFilenameLocation = Filename; - -} - -void CardDAV::GetServerContactData() -{ - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - wxString ServerCertFilename; - bool MatchingCert = FALSE; - - CURL *conn; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - // Try SSL first. - - - /* - char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; - //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); - - char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; - //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); - - char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; - //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); - - */ - - //std::string WriteDataString = std::string(ServerUploadData.mb_str()); - - std::map::iterator ActIter; - struct UploadDataStruc UploadData; - - - ActIter = ActivityListPtr->find((int)ItemIndex); - - //ActIter->second = 1; - - /*wxString CardDAVDataQuery = wxT("\r\n"); - CardDAVDataQuery.Append(wxT("\r\n")); - CardDAVDataQuery.Append(wxT("\r\n")); - CardDAVDataQuery.Append(wxT("\r\n")); - CardDAVDataQuery.Append(wxT(" \r\n")); - CardDAVDataQuery.Append(wxT("\r\n")); - CardDAVDataQuery.Append(wxT(""));*/ - - if (ServerSSL){ - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - ServerCertFilename = GetAccountDir(ServerAccount, TRUE); - - if (wxFile::Exists(ServerCertFilename) == TRUE){ - - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); - - } - - claconncode = (curl_easy_perform(conn)); - - // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without - // the local certificate in use. - - if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - - claconncode = (curl_easy_perform(conn)); - - // If claconncode is CURLE_OK then delete the certificate file as that - // is no longer needed. - - if (claconncode == CURLE_OK){ - - // Delete the certificate file. - - wxRemoveFile(ServerCertFilename); - - } - - } - - // Check if it fails with a CURLE_SSL_CACERT then compare - // the certificates as PEM files. - - if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ - - //curl_easy_cleanup(conn); - //conn = curl_easy_init(); - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - //claconncode = (curl_easy_perform(conn)); - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - wxString SSLLocalData; - wxString SSLServerData; - - 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")); - - wxFFile SSLLocalFile; - -#if wxABI_VERSION < 20900 - SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); -#else - SSLLocalFile.Open(ServerCertFilename, wxT("r")); -#endif - - // Load the recovery database for tasks not done. - - if (SSLLocalFile.IsOpened() == TRUE){ - - SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); - - - } - - SSLServerData = SSLDataIter->second; - - if (SSLLocalData == SSLServerData){ - - // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER - // and CURLOPT_SSL_VERIFYHOST off. - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - PageData.clear(); - PageHeader.clear(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); - - claconncode = (curl_easy_perform(conn)); - - MatchingCert = TRUE; - - } - - if (MatchingCert == FALSE){ - - claconncode = CURLE_SSL_CACERT; - return; - - } - - curl_easy_cleanup(sslerrconn); - - } - - // Sort out SSL error. - - // When SSL cert error occurs, connect again and fetch certificates. - // Display a message to the user explaining that an invalid - // certificate has been given and let the user decide what - // to do next. - - if (claconncode == CURLE_OK){ - - } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - // Replace conn with sslerrconn! - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - sslerrconncode = (curl_easy_perform(sslerrconn)); - - SSLCertCol = BuildSSLCollection(sslerrconn); - SSLCertCol.SuccessCode = 1; - - return; - - } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - return; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - return; - - } - } else { - - // No SSL. - - wxString EmptyString; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - - PageData.Clear(); - PageHeader.Clear(); - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", - GetHTTPCode()); - - return; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - return; - - } - - } - - return; - -} - -wxString CardDAV::GetPageData() -{ - - return PageData; - -} - -void CardDAV::GetServerETagValueThread() -{ - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - bool FilenameIsDirectory = FALSE; - CURL *conn; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - // Workout if path is directory or filename. - - /*if (ServerAddress){ - FilenameIsDirectory = TRUE; - } else { - FilenameIsDirectory = FALSE; - }*/ - - // Try SSL first. - - - /* - char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)]; - //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1)); - - char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)]; - //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1)); - - char *ServerAuthChar = new char[(ServerAuth.Length() - 1)]; - //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); - strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1)); - - */ - - //std::string WriteDataString = std::string(ServerUploadData.mb_str()); - - std::map::iterator ActIter; - struct UploadDataStruc UploadData; - - - ActIter = ActivityListPtr->find((int)ItemIndex); - - static const char* query = - "" - "" - "" - //"" - //" " - //"" - "" - "" - ""; - - if (ServerSSL){ - - wxString ServerCertFilename; - bool MatchingCert = FALSE; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - ServerCertFilename = GetAccountDir(ServerAccount, TRUE); - - if (wxFile::Exists(ServerCertFilename) == TRUE){ - - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); - - } - - claconncode = (curl_easy_perform(conn)); - - // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without - // the local certificate in use. - - if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - claconncode = (curl_easy_perform(conn)); - - // If claconncode is CURLE_OK then delete the certificate file as that - // is no longer needed. - - if (claconncode == CURLE_OK){ - - // Delete the certificate file. - - wxRemoveFile(ServerCertFilename); - - } - - } - - // Check if it fails with a CURLE_SSL_CACERT then compare - // the certificates as PEM files. - - if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ - - //curl_easy_cleanup(conn); - //conn = curl_easy_init(); - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - //claconncode = (curl_easy_perform(conn)); - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - PageData.clear(); - PageHeader.clear(); - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); - - wxString SSLLocalData; - wxString SSLServerData; - - 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")); - - wxFFile SSLLocalFile; - -#if wxABI_VERSION < 20900 - SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); -#else - SSLLocalFile.Open(ServerCertFilename, wxT("r")); -#endif - - // Load the recovery database for tasks not done. - - if (SSLLocalFile.IsOpened() == TRUE){ - - // Check if we are using wxWidgets version 2.8 or less and - // execute the required command accordingly. - - SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); - - - } - - SSLServerData = SSLDataIter->second; - - if (SSLLocalData == SSLServerData){ - - // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER - // and CURLOPT_SSL_VERIFYHOST off. - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - PageData.clear(); - PageHeader.clear(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); - - claconncode = (curl_easy_perform(conn)); - - MatchingCert = TRUE; - - } - - if (MatchingCert == FALSE){ - - claconncode = CURLE_SSL_CACERT; - return; - - } - - curl_easy_cleanup(sslerrconn); - - } - - // Sort out SSL error. - - // When SSL cert error occurs, connect again and fetch certificates. - // Display a message to the user explaining that an invalid - // certificate has been given and let the user decide what - // to do next. - - if (claconncode == CURLE_OK){ - - } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - // Replace conn with sslerrconn! - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - sslerrconncode = (curl_easy_perform(sslerrconn)); - - SSLCertCol = BuildSSLCollection(sslerrconn); - SSLCertCol.SuccessCode = 1; - - curl_easy_cleanup(conn); - curl_easy_cleanup(sslerrconn); - - return; - - } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - curl_easy_cleanup(conn); - - return; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - curl_easy_cleanup(conn); - - return; - - } - - } else { - - // No SSL. - - wxString EmptyString; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - PageData.Clear(); - PageHeader.Clear(); - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - return; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - return; - - } - - } - - xmlDocPtr xmlCardDAVDoc; - - xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); - - xmlNodePtr nodeLevel1; - xmlNodePtr nodeLevel2; - xmlNodePtr nodeLevel3; - xmlNodePtr nodeLevel4; - xmlNodePtr nodeLevel5; - xmlNodePtr nodeLevel6; - - std::map xmlDataMap; - - wxString DataFilename; - wxString ETagData; - - std::string xmlStringSafe; - - // Tranverse through the catacombs of the response to get our ETag for the file. - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - bool HREFFound = FALSE; - bool ETagFound = FALSE; - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") - ){ - - // Get the filename. - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") - ){ - - DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); - wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); - - while (wSTDFilename.HasMoreTokens()){ - - DataFilename = wSTDFilename.GetNextToken(); - - } - - HREFFound = TRUE; - - } - - - - } - - } else { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") - ){ - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - // Strip the quotes from the ETag. - - ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); - if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ - - ETagData.Remove(0, 1); - ETagData.RemoveLast(); - - } - - ETagFound = TRUE; - - } - - } - - } - - } - - } - - } - - } - - if (HREFFound == TRUE && ETagFound == TRUE){ - - // Add to the map data. - - xmlDataMap.insert(std::make_pair(DataFilename, ETagData)); - - HREFFound = FALSE; - ETagFound = FALSE; - - } - - - } - - xmlFreeDoc(xmlCardDAVDoc); - - // Get the first result. - - for (std::map::iterator iter = xmlDataMap.begin(); - iter != xmlDataMap.end(); ++iter){ - - ETagResult = iter->second; - break; - - } - - if (ETagResult.IsEmpty()){ - - return; - - } - - return; - -} - -wxString CardDAV::ETagValueResult(){ - - return ETagResult; - -} - -void CardDAV::GetServerETagValue(){ - - std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this); - ConnectThread.detach(); - -} - -void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){ - - ServerMethod = Method; - ServerFilenameLocation = FilenameLocation; - ServerUploadData = UploadData; - - // Check if ServerFilenameLocation has a / at - // the start and if not then append it. - - if (ServerFilenameLocation.Left(1) != wxT("/")){ - - // Not there so insert. - - ServerFilenameLocation = wxT("/") + ServerFilenameLocation; - - } - -} - -void CardDAV::SetupVariables(std::map *actlist, int actindex){ - - ActivityListPtr = actlist; - ItemIndex = actindex; - -} - -wxString CardDAV::GetETagData(){ - - return ETagData; - -} - -void CardDAV::SetUploadMode(bool IncMode){ - - UploadMode = IncMode; - -} - -void CardDAV::SetEditMode(bool EditModeInc){ - - EditMode = EditModeInc; - -} - -ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ - - ContactListData ContactListFinal; - std::map ContactList; - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - CURL *conn; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/"); - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - // Load the sync token file (if it exists). - - wxCharBuffer SyncDataBuffer; - wxString SyncData; - - SyncData.Clear(); - - SyncTokenInc.Trim(); - - if (!SyncTokenInc.IsEmpty()){ - - SyncData = wxT("\n"); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("")); - //SyncData.Trim(); - //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580")); - SyncData.Append(SyncTokenInc); - //SyncData.Trim(); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("1\n")); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT(" \n")); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("")); - - SyncDataBuffer = SyncData.ToUTF8(); - - } else { - - SyncData = wxT("\n"); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("1\n")); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT(" \n")); - SyncData.Append(wxT("\n")); - SyncData.Append(wxT("\n")); - - SyncDataBuffer = SyncData.ToUTF8(); - - } - - //static const char* query = SyncData.mb_str(); - - /*char *query = "\n\ - \n\ - data:,00378c55-1f44-44a2-a255-84f6560b5cac_580\n\ - 1\n\ - \n\ - \n\ - \n\ - \n";*/ - const char* query = SyncDataBuffer.data(); - - // Try SSL first. - - std::map::iterator ActIter; - struct UploadDataStruc UploadData; - - ActIter = ActivityListPtr->find((int)ItemIndex); - - curl_slist *slist = NULL; - - slist = curl_slist_append(slist, "Depth: 1"); - - if (ServerSSL){ - - wxString ServerCertFilename; - bool MatchingCert = FALSE; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - - ServerCertFilename = GetAccountDir(ServerAccount, TRUE); - - if (wxFile::Exists(ServerCertFilename) == TRUE){ - - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); - - } - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - claconncode = (curl_easy_perform(conn)); - - // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without - // the local certificate in use. - - if (claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - claconncode = (curl_easy_perform(conn)); - - // If claconncode is CURLE_OK then delete the certificate file as that - // is no longer needed. - - if (claconncode == CURLE_OK){ - - // Delete the certificate file. - - wxRemoveFile(ServerCertFilename); - - } - - } - - // Check if it fails with a CURLE_SSL_CACERT then compare - // the certificates as PEM files. - - if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ - - //curl_easy_cleanup(conn); - //conn = curl_easy_init(); - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - //claconncode = (curl_easy_perform(conn)); - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - wxString SSLLocalData; - wxString SSLServerData; - - 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")); - - wxFFile SSLLocalFile; - -#if wxABI_VERSION < 20900 - SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r")); -#else - SSLLocalFile.Open(ServerCertFilename, wxT("r")); -#endif - - // Load the recovery database for tasks not done. - - if (SSLLocalFile.IsOpened() == TRUE){ - - // Check if we are using wxWidgets version 2.8 or less and - // execute the required command accordingly. - - SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto()); - - - } - - SSLServerData = SSLDataIter->second; - - if (SSLLocalData == SSLServerData){ - - // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER - // and CURLOPT_SSL_VERIFYHOST off. - - curl_easy_cleanup(conn); - conn = curl_easy_init(); - - PageHeader.clear(); - PageData.clear(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); - curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0); - - claconncode = (curl_easy_perform(conn)); - - MatchingCert = TRUE; - - } - - if (MatchingCert == FALSE){ - - claconncode = CURLE_SSL_CACERT; - return ContactListFinal; - - } - - curl_easy_cleanup(sslerrconn); - - } - - // Sort out SSL error. - - // When SSL cert error occurs, connect again and fetch certificates. - // Display a message to the user explaining that an invalid - // certificate has been given and let the user decide what - // to do next. - - if (claconncode == CURLE_OK){ - - } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){ - - CURL *sslerrconn; - sslerrconn = curl_easy_init(); - CURLcode sslerrconncode; - - wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - - // Replace conn with sslerrconn! - - curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8)); - curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - - sslerrconncode = (curl_easy_perform(sslerrconn)); - - SSLCertCol = BuildSSLCollection(sslerrconn); - SSLCertCol.SuccessCode = 1; - - return ContactListFinal; - - } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - return ContactListFinal; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %d\n", http_code); - - return ContactListFinal; - - } - - SSLCertCol = BuildSSLCollection(conn); - - } else { - - // No SSL. - - wxString EmptyString; - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT"); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); - - //UploadData.readptr = &CardDAVDataQuery; - //UploadData.sizeleft = CardDAVDataQuery.Len(); - //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1); - //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData); - //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc); - - //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - - PageData.Clear(); - PageHeader.Clear(); - - claconncode = (curl_easy_perform(conn)); - - if (claconncode == CURLE_OK){ - - - - } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %i\n", http_code); - - return ContactListFinal; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(claconncode)); - int http_code = 0; - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); - fprintf(stderr, "Error code was: %i\n", http_code); - - return ContactListFinal; - - } - - } - - xmlDocPtr xmlCardDAVDoc; - xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); - - xmlNodePtr nodeLevel1; - xmlNodePtr nodeLevel2; - xmlNodePtr nodeLevel3; - xmlNodePtr nodeLevel4; - xmlNodePtr nodeLevel5; - xmlNodePtr nodeLevel6; - - xmlNodePtr nodeStatusLv1; - xmlNodePtr nodeStatusLv2; - - std::map xmlDataMap; - std::map ServerETagData; - - wxString DataFilename; - wxString DataSyncToken; - int DataFileStatus; - wxString ETagData; - bool SyncTokenFound = FALSE; - - std::string xmlStringSafe; - - // Tranverse through the catacombs of the response to get our ETag for the file and - // the server syncronisation token. - - // Start by getting all the server ETag data. - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - DataFileStatus = 0; - bool HREFFound = FALSE; - bool ETagFound = FALSE; - bool HTTPStatus = FALSE; - - if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") - ){ - - // Get the filename. - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") - ){ - - DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); - wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); - - while (wSTDFilename.HasMoreTokens()){ - - DataFilename = wSTDFilename.GetNextToken(); - - } - - HREFFound = TRUE; - - } - - - - } - - - } else { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeStatusLv1 = nodeLevel3->children; - nodeStatusLv1 != NULL; - nodeStatusLv1 = nodeStatusLv1->next) - { - - if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){ - - DataFileStatus = 2; - - HTTPStatus = TRUE; - - } - - if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") || - !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") || - !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE) - { - - // Get the filename. - - for (nodeStatusLv2 = nodeStatusLv1->children; - nodeStatusLv2 != NULL; - nodeStatusLv2 = nodeStatusLv2->next) - { - - if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text") - ){ - - if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){ - - DataFileStatus = 1; - - HTTPStatus = TRUE; - - // This is currently in a WebDAV draft and may hopefully be enabled when this changes. - - //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){ - - // DataFileStatus = 0; - - } - - } - - - - } - - } - - - } - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") - ){ - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - // Strip the quotes from the ETag. - - ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); - if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ - - ETagData.Remove(0, 1); - ETagData.RemoveLast(); - - } - - ETagFound = TRUE; - - } - - } - - } - - } - - } - - if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){ - - // Add to the map data. - - FileSyncData SData; - - SData.ETagData = ETagData; - SData.DataFlag = DataFileStatus; - - ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); - - } - - // Reset the values. - - HREFFound = FALSE; - ETagFound = FALSE; - HTTPStatus = FALSE; - - } - - if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") || - !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") || - !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) && - SyncTokenFound == FALSE - ){ - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text") - ){ - - DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content); - - SyncTokenFound = TRUE; - - } - - } - - } - - } - - } - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - DataFileStatus = 0; - bool HREFFound = FALSE; - bool ETagFound = FALSE; - bool HTTPStatus = FALSE; - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") - ){ - - // Get the filename. - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") - ){ - - DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); - wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); - - while (wSTDFilename.HasMoreTokens()){ - - DataFilename = wSTDFilename.GetNextToken(); - - } - - HREFFound = TRUE; - - } - - - - } - - - } else { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeStatusLv1 = nodeLevel3->children; - nodeStatusLv1 != NULL; - nodeStatusLv1 = nodeStatusLv1->next) - { - - if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){ - - DataFileStatus = 2; - - HTTPStatus = TRUE; - - } - - if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") || - !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") || - !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE) - { - - // Get the filename. - - for (nodeStatusLv2 = nodeStatusLv1->children; - nodeStatusLv2 != NULL; - nodeStatusLv2 = nodeStatusLv2->next) - { - - if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text") - ){ - - if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){ - - DataFileStatus = 1; - - HTTPStatus = TRUE; - - // This is currently in a WebDAV draft and may hopefully be enabled when this changes. - - //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){ - - // DataFileStatus = 0; - - } - - } - - - - } - - } - - - } - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || - !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") - ){ - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - // Strip the quotes from the ETag. - - ETagData = wxString::FromUTF8((const char*)nodeLevel6->content); - if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){ - - ETagData.Remove(0, 1); - ETagData.RemoveLast(); - - } - - ETagFound = TRUE; - - } - - } - - } - - } - - } - - } - - if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){ - - FileSyncData SData; - - SData.ETagData = wxT(""); - SData.DataFlag = DataFileStatus; - - ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); - - } - - if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){ - - // Add to the map data. - - FileSyncData SData; - - SData.ETagData = ETagData; - SData.DataFlag = DataFileStatus; - - ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData)); - - } - - // Reset the values. - - HREFFound = FALSE; - ETagFound = FALSE; - HTTPStatus = FALSE; - DataFilename.Clear(); - - if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") || - !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") || - !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) && - SyncTokenFound == FALSE - ){ - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") || - !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text") - ){ - - DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content); - - SyncTokenFound = TRUE; - - } - - } - - } - - } - - } - - // Get the sync token. - - if (SyncTokenFound == TRUE){ - - ContactListFinal.SyncToken = DataSyncToken; - - } else { - - } - - SleepFor(2000000000); - - /*timespec n1, n2; - - n1.tv_sec = 0; - n1.tv_nsec = 2000000000L; - - nanosleep(&n1, &n2);*/ - - xmlFreeDoc(xmlCardDAVDoc); - curl_easy_cleanup(conn); - - SyncDataBuffer.reset(); - - // Get the first result. - - return ContactListFinal; - -} - -int CardDAV::GetResultCode(){ - - return (int)claconncode; - -} - -int CardDAV::GetHTTPCode(){ - - return HTTPErrorCode; - -} - -wxString CardDAV::GetErrorBuffer(){ - - wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer); + wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer); return ErrorBuffer; } -wxString CardDAV::GetDefaultAddressBookURL(){ - - // First: Get the principal UID address. - - PageData.Clear(); - PageHeader.Clear(); - - SSLStatus = TRUE; - AuthPassed = TRUE; - AbortConnection = FALSE; - - CURL *conn; - CURLcode conncode; - wxString ServerAddressURL; - wxString ServerAuth; - wxString ServerAddressSSL; - wxString ServerAddressNormal; - - conn = curl_easy_init(); - - struct curl_slist *connhd = NULL; - struct curl_slist *connhd2 = NULL; - struct curl_slist *connhd3 = NULL; - - connhd = curl_slist_append(connhd, "Depth: 0"); - connhd = curl_slist_append(connhd, "Prefer: return-minimal"); - connhd = curl_slist_append(connhd, "Content-Type: application/xml; charset=utf-8"); - - connhd2 = curl_slist_append(connhd2, "Depth: 0"); - connhd2 = curl_slist_append(connhd2, "Prefer: return-minimal"); - connhd2 = curl_slist_append(connhd2, "Content-Type: application/xml; charset=utf-8"); - - connhd3 = curl_slist_append(connhd3, "Depth: 1"); - connhd3 = curl_slist_append(connhd3, "Prefer: return-minimal"); - connhd3 = curl_slist_append(connhd3, "Content-Type: application/xml; charset=utf-8"); - - struct CardDAVCURLPasser { - - CardDAV *Data; - bool HeaderMode = TRUE; - - } CardDAVHeader, CardDAVFooter; - - CardDAVHeader.Data = this; - CardDAVHeader.HeaderMode = TRUE; - - CardDAVFooter.Data = this; - CardDAVFooter.HeaderMode = FALSE; - - wxString Data1; - wxString Data2; - - wxString ETag; - wxString ETagOriginal; - wxString ETagServer; - - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); - ServerAddressSSL = wxT("https://") + ServerAddressURL; - ServerAddressNormal = wxT("http://") + ServerAddressURL; - - ServerAuth = ServerUser + wxT(":") + ServerPass; - - wxString SAURLPrincipals; - wxString SAURLPrincipalURL; - wxString SAURLAddressURL; - - if (ServerSSL){ - - SAURLPrincipals = ServerAddressSSL + wxT("principals/"); - SAURLPrincipalURL = ServerAddressSSL; - SAURLAddressURL = ServerAddressSSL; - - } else { - - SAURLPrincipals = ServerAddressNormal + wxT("principals/"); - SAURLPrincipalURL = ServerAddressNormal; - SAURLAddressURL = ServerAddressNormal; - - } - - wxString FinalPrefix; - - struct UploadDataStruc UploadData; - - // Setup the first query finding out where the principal URL is. - - const char* query = "\n" - "\n" - " " - " \n" - " " - ""; - - // Setup the second query finding out where the address book home URL is. - - const char* query2 = "\n" - "\n" - " \n" - " \n" - " \n" - ""; - - // Setup the third query finding out where the default address book URL is. - - const char* query3 = "\n" - "\n" - " \n" - " \n" - " \n" - ""; - - if (ServerSSL){ - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd); - - if (AllowSelfSign == TRUE){ - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); - } - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - *ServerResult = TRUE; - AuthPassed = TRUE; - ValidResponse = TRUE; - SSLStatus = TRUE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - return wxT(""); - - } - - } else { - - // No SSL. - - // Do an initial connection (incase of Digest authentication). - - PageData.Clear(); - PageHeader.Clear(); - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd); - - conncode = (curl_easy_perform(conn)); - - // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, - // then bring up the conflict resolution form. - - if (EditMode == TRUE){ - - } - - if (conncode == CURLE_OK){ - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", - GetHTTPCode()); - - return wxT(""); - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - return wxT(""); - - } - - } - - // Process the XML data from the application. - - xmlDocPtr xmlCardDAVDoc; - xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); - - xmlNodePtr nodeLevel1; - xmlNodePtr nodeLevel2; - xmlNodePtr nodeLevel3; - xmlNodePtr nodeLevel4; - xmlNodePtr nodeLevel5; - xmlNodePtr nodeLevel6; - xmlNodePtr nodeLevel7; - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") - ){ - - // Found the part so extract the principal URL address. - - for (nodeLevel7 = nodeLevel6->children; - nodeLevel7 != NULL; - nodeLevel7 = nodeLevel7->next) - { - - SAURLPrincipalURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content)); - - } - - } - - } - - } - - } - - } - - } - - } - - xmlFreeDoc(xmlCardDAVDoc); - PageData.Clear(); - PageHeader.Clear(); - - // Second: Get the addressbook-home-set - - curl_easy_reset(conn); - - if (ServerSSL){ - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2); - - if (AllowSelfSign == TRUE){ - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); - } - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - *ServerResult = TRUE; - AuthPassed = TRUE; - SSLStatus = TRUE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - ValidResponse = FALSE; - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - return wxT(""); - - } - - } else { - - // No SSL. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2); - - conncode = (curl_easy_perform(conn)); - - // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, - // then bring up the conflict resolution form. - - if (EditMode == TRUE){ - - } - - if (conncode == CURLE_OK){ - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", - GetHTTPCode()); - - ValidResponse = FALSE; - - return wxT(""); - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ValidResponse = FALSE; - - return wxT(""); - - } - - } - - xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") - ){ - - // Found the part so extract the principal URL address. - - for (nodeLevel7 = nodeLevel6->children; - nodeLevel7 != NULL; - nodeLevel7 = nodeLevel7->next) - { - - SAURLAddressURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content)); - - } - - } - - } - - } - - } - - } - - } - - } - - xmlFreeDoc(xmlCardDAVDoc); - PageData.Clear(); - PageHeader.Clear(); - - // Finally: Get the default-addressbook-URL from the addressbook-home-set address. - - curl_easy_reset(conn); - - if (ServerSSL){ - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3); - - if (AllowSelfSign == TRUE){ - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); - } - - conncode = (curl_easy_perform(conn)); - - if (conncode == CURLE_OK){ - - *ServerResult = TRUE; - AuthPassed = TRUE; - SSLStatus = TRUE; - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - *ServerResult = FALSE; - ValidResponse = FALSE; - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - return wxT(""); - - } - - } else { - - // No SSL. - - curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); - curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); - curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE); - curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT); - curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8)); - curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); - curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); - curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); - curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc); - curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3); - curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3)); - curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3); - - conncode = (curl_easy_perform(conn)); - - // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG, - // then bring up the conflict resolution form. - - if (EditMode == TRUE){ - - } - - if (conncode == CURLE_OK){ - - } else if (conncode == CURLE_HTTP_RETURNED_ERROR){ - - curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode); - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n", - GetHTTPCode()); - - ValidResponse = FALSE; - - return wxT(""); - - } else { - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(conncode)); - - ValidResponse = FALSE; - - return wxT(""); - - } - - } - - xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0); - - for (nodeLevel1 = xmlCardDAVDoc->children; - nodeLevel1 != NULL; - nodeLevel1 = nodeLevel1->next) - { - - for (nodeLevel2 = nodeLevel1->children; - nodeLevel2 != NULL; - nodeLevel2 = nodeLevel2->next) - { - - - for (nodeLevel3 = nodeLevel2->children; - nodeLevel3 != NULL; - nodeLevel3 = nodeLevel3->next) - { - - for (nodeLevel4 = nodeLevel3->children; - nodeLevel4 != NULL; - nodeLevel4 = nodeLevel4->next) - { - - for (nodeLevel5 = nodeLevel4->children; - nodeLevel5 != NULL; - nodeLevel5 = nodeLevel5->next) - { - - for (nodeLevel6 = nodeLevel5->children; - nodeLevel6 != NULL; - nodeLevel6 = nodeLevel6->next) - { - - if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") || - !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href") - ){ - - // Found the part so extract the principal URL address. - - for (nodeLevel7 = nodeLevel6->children; - nodeLevel7 != NULL; - nodeLevel7 = nodeLevel7->next) - { - - FinalPrefix = wxString::FromUTF8((const char*)nodeLevel7->content); - - } - - } - - } - - } - - } - - } - - } - - } - - xmlFreeDoc(xmlCardDAVDoc); - PageData.Clear(); - PageHeader.Clear(); - - return FinalPrefix; - -} - SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){ SSLCertCollection SSLCertInfo; diff --git a/source/carddav/carddav.h b/source/carddav/carddav.h index e38c614..dbbcc9b 100644 --- a/source/carddav/carddav.h +++ b/source/carddav/carddav.h @@ -21,6 +21,12 @@ struct ContactListData{ std::map ListData; }; +struct UploadDataStruc{ + wxString *readptr; + long sizeleft; + int seek = 0; +}; + /*struct CertificateData{ std::multimap CertificateData; bool CertValid; @@ -38,6 +44,7 @@ struct CertificateCollection{ size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *userdata); int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp); +size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata); class CardDAV {