Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
CardDAV: Set CURLOPT_SSL_VERIFYSTATUS to 0 when using certificate file
[xestiaab/.git] / source / carddav2 / carddav2.cpp
index 494468c..dd70bab 100644 (file)
 
 #include "carddav2.h"
 
-#include <iostream>
-
 using namespace std;
 
+CardDAV2::CardDAV2(string ServerAddress, int ServerPort, string ServerUser, string ServerPass, bool ServerSSL){
+
+       this->ServerAddress = ServerAddress;
+       this->ServerPort = ServerPort;
+       this->ServerUser = ServerUser;
+       this->ServerPass = ServerPass;
+       this->ServerSSL = ServerSSL;
+
+       TestMode = true;
+       this->SetupConnectionObject();
+
+}
+
+CardDAV2::CardDAV2(string ServerAddress, int ServerPort, string ServerUser, string ServerPass, bool ServerSSL, string ServerPrefix, string ServerAccount){
+
+       this->ServerAddress = ServerAddress;
+       this->ServerPort = ServerPort;
+       this->ServerUser = ServerUser;
+       this->ServerPass = ServerPass;
+       this->ServerSSL = ServerSSL;
+       this->ServerPrefix = ServerPrefix;
+       this->ServerAccount = ServerAccount;
+
+
+       TestMode = false;
+       this->SetupConnectionObject();
+
+}
+
 size_t CardDAV2::WritebackFunc(char *ptr, size_t size, size_t nmemb, void *stream){
-       
-       return static_cast<CardDAV2*>(stream)->WritebackFuncImplementation(ptr, size, nmemb, stream);
+
+       return static_cast<CardDAV2PassObject*>(stream)->CardDAV2Object->WritebackFuncImplementation(ptr, size, nmemb, stream);
        
 }
-       
+
 size_t CardDAV2::WritebackFuncImplementation(char *ptr, size_t size, size_t nmemb, void *stream){
        
        // Writeback function for the CardDAV object.
                
-       string *data = static_cast<string*>(stream);
-       data->append(ptr);
+       CardDAV2PassObject *data = static_cast<CardDAV2PassObject*>(stream);
+       data->DataSetting->append(ptr);
        
        // Get the SSL engine pointer and trust if required on certain operating systems.
-       
-       if (ServerSSL){
-       
+
+       if (data->ServerUsingSSL == true) {
+
 #if defined(__APPLE__)
-       
+
                const struct curl_tlssessioninfo *TLSInfo;
                CURLcode TLSCode;
-               CURL *Connection = GetConnectionObject();
-               TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
-       
-               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
-                       SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject);
+               TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo);
+
+               SecTrustRef CertificateData;
+               
+               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) {
+                       SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &CertificateData);
+                       data->SSLContext = CertificateData;
                }
-       
+
 #elif defined(__WIN32__)
 
                const struct curl_tlssessioninfo *TLSInfo;
                CURLcode TLSCode;
-               CURL *Connection = GetConnectionObject();
-               TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
+               TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo);
 
-               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
+               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) {
 
                        // Free the previous certificate data.
 
-                       CertFreeCertificateContext(CertificateData);
+                       //CertFreeCertificateContext(CertificateData);
+
+                       PCCERT_CONTEXT CertificateData;
 
                        PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
                        SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
 
+                       data->SSLContext = CertificateData;
+
                }
 
 #endif
 
        }
-       
+
        return size * nmemb;
 
 }
 
+void CardDAV2::SetCertificateData() {
+
+}
+
 CardDAV2::~CardDAV2(){
        
        curl_easy_cleanup(ConnectionSession);
@@ -85,13 +121,35 @@ CardDAV2::~CardDAV2(){
                curl_slist_free_all(HeaderList);
                HeaderList = nullptr;
        }
+
+#if defined(__WIN32__)
+
+       if (CertificateData != nullptr) {
+
+               CertFreeCertificateContext(CertificateData);
+
+       }
+
+#endif
        
 }
 
 #if defined(__APPLE__)
 
+SecTrustRef CardDAV2::BuildSSLCollection(){
+       
+       return CertificateData;
+       
+}
+
 #elif defined(__WIN32__)
 
+PCCERT_CONTEXT CardDAV2::BuildSSLCollection(){
+
+       return CertificateData;
+
+}
+
 #else
 
 SSLCertCollectionString CardDAV2::BuildSSLCollection(){
@@ -109,13 +167,13 @@ SSLCertCollectionString CardDAV2::BuildSSLCollection(){
 
        certptr.certdata = NULL;
        
-       curl_easy_getinfo(ConnectionSession, CURLINFO_CERTINFO, &certptr.certinfo);
-
+       CURLcode result = curl_easy_getinfo(ConnectionSession, CURLINFO_CERTINFO, &certptr.certinfo);
+       
        std::string CertPropName;
        std::string CertPropValue;
-
+       
        for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
-
+               
                struct curl_slist *slist;
                SSLCertDataString SSLCertDataInc;
                
@@ -151,13 +209,13 @@ SSLCertCollectionString CardDAV2::BuildSSLCollection(){
 
 }
 
-void CardDAV2::BypassSSLVerification(bool EnableBypass){
+#endif
+
+void CardDAV2::BypassSSLVerification(bool EnableBypass) {
        EnableSSLBypass = EnableBypass;
        SSLSelfSigned = EnableBypass;
 }
 
-#endif
-
 void CardDAV2::SetupConnectionObject(){
        ConnectionSession = curl_easy_init();
 }
@@ -173,7 +231,7 @@ COConnectResult CardDAV2::Connect(bool DoAuthentication){
        
        COConnectResult ConnectResult = COCONNECT_UNITTESTFAIL;
        string ServerAddressURL = BuildURL("/principals/");
-
+       
        curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
        
        if (TestMode == true){
@@ -189,6 +247,7 @@ COConnectResult CardDAV2::Connect(bool DoAuthentication){
                        SSLVerified = COSSL_VERIFIED;
                        ConnectResult = COCONNECT_OK;
                        break;
+               case CURLE_SSL_INVALIDCERTSTATUS:
                case CURLE_SSL_CACERT:
                case CURLE_SSL_CONNECT_ERROR:
                        SSLStatus = true;
@@ -200,6 +259,26 @@ COConnectResult CardDAV2::Connect(bool DoAuthentication){
                        break;
        };
        
+       // Set the certificate data (if required).
+
+#if defined(__APPLE__)
+       
+       if (ServerSSL) {
+               
+               CertificateData = PageHeaderObject.SSLContext;
+               
+       }
+       
+#elif defined(__WIN32__)
+
+       if (ServerSSL) {
+
+               CertificateData = PageHeaderObject.SSLContext;
+
+       }
+
+#endif
+
        // Check if an error occured before continuing.
        
        // Check if authentication was successful.
@@ -476,7 +555,7 @@ COServerResponse CardDAV2::GetDefaultPrefix(string *ServerPrefix){
                ValidResponse = false;                  
        }
        
-       if (ValidResponse == false && AuthPassed == false){
+       if (ValidResponse == false || AuthPassed == false){
                ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
                ServerResponse.EntityTag = "";
                ServerResponse.SessionCode = SessionResult;
@@ -809,7 +888,7 @@ COServerResponse CardDAV2::AddContact(std::string Location, std::string Data){
                ValidResponse = false;                  
        }
        
-       if (ValidResponse == false && AuthPassed == false){
+       if (ValidResponse == false || AuthPassed == false){
                ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
                ServerResponse.EntityTag = "";
                ServerResponse.SessionCode = SessionResult;
@@ -830,162 +909,635 @@ COServerResponse CardDAV2::AddContact(std::string Location, std::string Data){
 }
 
 COServerResponse CardDAV2::EditContact(std::string Location, std::string Data){
-       
-}
 
-COServerResponse CardDAV2::DeleteContact(std::string Location, std::string EntityTag){
-       
-}
-
-COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){
-       
-}
+       // Check if authentication was successful, otherwise don't do anything.
 
-COServerResponse CardDAV2::GetContact(std::string Location){
+       COServerResponse ServerResponse;
        
-}
+       if (AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = 0;
+               ServerResponse.ResultCode = 0;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
 
-COContactList CardDAV2::GetContactList(std::string SyncToken){
-       
-}
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
        
-bool CardDAV2::CanDoProcessing(){
-       return CanProcess;
-}
-
-bool CardDAV2::CanDoSSL(){
-       return SSLStatus;
-}
-
-COSSLVerified CardDAV2::SSLVerify(){
-       return SSLVerified;
-}
-
-bool CardDAV2::AbleToLogin(){
-       return AuthPassed;
-}
-
-bool CardDAV2::HasValidResponse(){
-       return ValidResponse;
-}
-
-bool CardDAV2::IsSelfSigned(){
-       return SSLSelfSigned;
-}
-
-void CardDAV2::SetupDefaultParametersNonSSL(bool DoAuthentication){
+       string ServerAddressURL = BuildURL(ServerPrefix + Location);
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PUT");
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, Data.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(Data.c_str()));
        
-       std::string ServerAddress = "";
+       HeaderList = curl_slist_append(HeaderList, "Content-Type: text/vcard; charset=utf-8");
 
-       string ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + "/";
-       string UsernamePassword = ServerUser + ":" + ServerPass;
-       
-       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddress.c_str());
-       curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
-       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
-       curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
-       curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
-       curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
-       curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
-       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
-       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
        
-       if (DoAuthentication == true){
-               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
        } else {
-               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
+               SessionResult = curl_easy_perform(ConnectionSession);
        }
        
-}
-
-void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
-       
-       // Setup the default parameters.
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
        
-       string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
-       string UsernamePassword = ServerUser + ":" + ServerPass;
+       long SessionResponseCode = 0;
        
-       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
-       curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
-       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
-       curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
-       curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
-       curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
-       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
-       curl_easy_setopt(ConnectionSession, CURLOPT_ERRORBUFFER, SessionErrorBuffer);
-       curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
-       curl_easy_setopt(ConnectionSession, CURLOPT_CERTINFO, 1);
-       curl_easy_setopt(ConnectionSession, CURLOPT_VERBOSE, 1);
-       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
-       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
        
-       if (DoAuthentication == true){
-               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+       if (SessionResponseCode == 200 || SessionResponseCode == 201 || SessionResponseCode == 204){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
        } else {
-               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
+               AuthPassed = false;
+               ValidResponse = false;                  
        }
        
-       if (EnableSSLBypass == true){
-               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 0);
-               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 0);
-       } else {
-               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 2);
-               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 1);         
+       if (ValidResponse == false || AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = SessionResult;
+               ServerResponse.ResultCode = SessionResponseCode;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
        }
        
-       if (TestMode == false && ServerAccount.size() > 0){
-               
-               // Check if the server certificate file exists.
-               
-               string CertificateFilename = GetAccountDir(ServerAccount, true);
-               
-               if (wxFile::Exists(CertificateFilename)){
-                       
-                       curl_easy_setopt(ConnectionSession, CURLOPT_CAINFO, CertificateFilename.c_str());
-                       
-               }
-               
-       }
+       CanProcess = true;
+       
+       ServerResponse.RequestResult = COREQUEST_OK;
+       ServerResponse.EntityTag = "";
+       ServerResponse.SessionCode = SessionResult;
+       ServerResponse.ResultCode = SessionResponseCode;
+       ServerResponse.ResultMessage = SessionErrorBuffer;
+       return ServerResponse;
        
 }
 
-string CardDAV2::BuildURL(string URI){
+COServerResponse CardDAV2::DeleteContact(std::string Location){
        
-       string ServerAddressURL;
+       // Check if authentication was successful, otherwise don't do anything.
+
+       COServerResponse ServerResponse;
        
-       if (SSLStatus == true){
-               ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;      
-       } else {
-               ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;
+       if (AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = 0;
+               ServerResponse.ResultCode = 0;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
        }
-       
-       return ServerAddressURL;
-       
-}
 
-string CardDAV2::GetErrorMessage(){
-       
-       ErrorMessage = SessionErrorBuffer;      
-       return ErrorMessage;
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
        
-}
-
-void CardDAV2::ResetResults(){
+       string ServerAddressURL = BuildURL(ServerPrefix + Location);
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "DELETE");
        
-       SSLStatus = false;
-       COSSLVerified SSLVerified = COSSL_NORESULT;
-       ValidResponse = false;
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
+       } else {
+               SessionResult = curl_easy_perform(ConnectionSession);
+       }
+       
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
+       
+       long SessionResponseCode = 0;
+       
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+       
+       if (SessionResponseCode == 200 || SessionResponseCode == 202 || SessionResponseCode == 204){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else {
+               AuthPassed = false;
+               ValidResponse = false;                  
+       }
+       
+       if (ValidResponse == false || AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = SessionResult;
+               ServerResponse.ResultCode = SessionResponseCode;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
+       
+       CanProcess = true;
+       
+       ServerResponse.RequestResult = COREQUEST_OK;
+       ServerResponse.EntityTag = "";
+       ServerResponse.SessionCode = SessionResult;
+       ServerResponse.ResultCode = SessionResponseCode;
+       ServerResponse.ResultMessage = SessionErrorBuffer;
+       return ServerResponse;
+       
+}
+
+COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){
+       
+       // Check if authentication was successful, otherwise don't do anything.
+
+       COServerResponse ServerResponse;
+       
+       if (AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = 0;
+               ServerResponse.ResultCode = 0;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
+
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
+       
+       static const char* GetETagQuery =
+       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
+       "<C:addressbook-query xmlns:D=\"DAV:\""
+       "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
+       "<D:prop><D:getetag/>"
+       "</D:prop>"
+       "<C:filter/>"
+       "</C:addressbook-query>";
+       
+       string ServerAddressURL = BuildURL(ServerPrefix + Location);
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, GetETagQuery);
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(GetETagQuery));
+       
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
+       } else {
+               SessionResult = curl_easy_perform(ConnectionSession);
+       }
+       
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
+       
+       long SessionResponseCode = 0;
+       
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+       
+       if (SessionResponseCode == 207){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else {
+               AuthPassed = false;
+               ValidResponse = false;                  
+       }
+       
+       if (ValidResponse == false || AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = SessionResult;
+               ServerResponse.ResultCode = SessionResponseCode;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
+       
+       CanProcess = true;
+       
+       ServerResponse.RequestResult = COREQUEST_OK;
+       ServerResponse.EntityTag = GetETagValue();
+       ServerResponse.SessionCode = SessionResult;
+       ServerResponse.ResultCode = SessionResponseCode;
+       ServerResponse.ResultMessage = SessionErrorBuffer;
+       
+       return ServerResponse;
+       
+}
+
+COServerResponse CardDAV2::GetContact(std::string Location, std::string *ContactData){
+       
+       // Check if authentication was successful, otherwise don't do anything.
+
+       COServerResponse ServerResponse;
+       
+       if (AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = 0;
+               ServerResponse.ResultCode = 0;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
+
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
+       
+       string ServerAddressURL = BuildURL(ServerPrefix + Location);
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
+       
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
+       } else {
+               SessionResult = curl_easy_perform(ConnectionSession);
+       }
+       
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
+       
+       long SessionResponseCode = 0;
+       
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+       
+       if (SessionResponseCode == 200){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else {
+               AuthPassed = false;
+               ValidResponse = false;                  
+       }
+       
+       if (ValidResponse == false && AuthPassed == false){
+               ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerResponse.EntityTag = "";
+               ServerResponse.SessionCode = SessionResult;
+               ServerResponse.ResultCode = SessionResponseCode;
+               ServerResponse.ResultMessage = "";
+               return ServerResponse;
+       }
+       
+       CanProcess = true;
+       
+       ServerResponse.RequestResult = COREQUEST_OK;
+       ServerResponse.EntityTag = "";
+       ServerResponse.SessionCode = SessionResult;
+       ServerResponse.ResultCode = SessionResponseCode;
+       ServerResponse.ResultMessage = SessionErrorBuffer;
+       
+       (*ContactData) = PageData;
+       
+       return ServerResponse;
+       
+}
+
+COContactList CardDAV2::GetContactList(std::string SyncToken){
+       
+       COContactList ServerContactList;
+       
+       // Check if authentication was successful, otherwise don't do anything.
+       
+       if (AuthPassed == false){
+               ServerContactList.ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerContactList.ServerResponse.EntityTag = "";
+               ServerContactList.ServerResponse.SessionCode = 0;
+               ServerContactList.ServerResponse.ResultCode = 0;
+               ServerContactList.ServerResponse.ResultMessage = "";
+               return ServerContactList;
+       }
+
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
+       
+       std::string SyncData;
+       
+       if (SyncToken.size() > 0){
+               
+               SyncData = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+               "<D:sync-collection xmlns:D=\"DAV:\"\n"
+               " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+               "<D:sync-token>";
+               SyncData.append(SyncToken);
+               SyncData.append("</D:sync-token>\n"
+               "<D:sync-level>1</D:sync-level>\n"
+               "<D:prop>\n"
+               "       <D:getetag/>\n"
+               "</D:prop>\n"
+               "</D:sync-collection>");
+       
+       } else {
+               
+               SyncData = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+               "<D:sync-collection xmlns:D=\"DAV:\"\n"
+               " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+               "<D:sync-level>1</D:sync-level>\n"
+               "<D:prop>\n"
+               "       <D:getetag/>\n"
+               "</D:prop>\n"
+               "</D:sync-collection>";
+
+       }
+       
+       string ServerAddressURL = BuildURL(ServerPrefix);
+       
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, SyncData.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(SyncData.c_str()));
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT");
+       
+       HeaderList = curl_slist_append(HeaderList, "Content-Type: application/xml; charset=utf-8");
+       HeaderList = curl_slist_append(HeaderList, "Depth: 1");
+
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
+       
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
+       } else {
+               SessionResult = curl_easy_perform(ConnectionSession);
+       }
+       
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
+       
+       long SessionResponseCode = 0;
+       
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+       
+       if (SessionResponseCode == 207){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else {
+               AuthPassed = false;
+               ValidResponse = false;                  
+       }
+       
+       if (ValidResponse == false || AuthPassed == false){
+               ServerContactList.ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerContactList.ServerResponse.EntityTag = "";
+               ServerContactList.ServerResponse.SessionCode = SessionResult;
+               ServerContactList.ServerResponse.ResultCode = SessionResponseCode;
+               ServerContactList.ServerResponse.ResultMessage = "";
+               return ServerContactList;
+       }
+       
+       CanProcess = true;
+       
+       ProcessContactData(&ServerContactList);
+       
+       ServerContactList.ServerResponse.RequestResult = COREQUEST_OK;
+       ServerContactList.ServerResponse.EntityTag = "";
+       ServerContactList.ServerResponse.SessionCode = SessionResult;
+       ServerContactList.ServerResponse.ResultCode = SessionResponseCode;
+       ServerContactList.ServerResponse.ResultMessage = SessionErrorBuffer;
+       
+       return ServerContactList;
+       
+}
+       
+bool CardDAV2::CanDoProcessing(){
+       return CanProcess;
+}
+
+bool CardDAV2::CanDoSSL(){
+       return SSLStatus;
+}
+
+COSSLVerified CardDAV2::SSLVerify(){
+       return SSLVerified;
+}
+
+bool CardDAV2::AbleToLogin(){
+       return AuthPassed;
+}
+
+bool CardDAV2::HasValidResponse(){
+       return ValidResponse;
+}
+
+bool CardDAV2::IsSelfSigned(){
+       return SSLSelfSigned;
+}
+
+void CardDAV2::SetupDefaultParametersNonSSL(bool DoAuthentication){
+       
+       std::string ServerAddress = "";
+
+       string ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + "/";
+       string UsernamePassword = ServerUser + ":" + ServerPass;
+
+       PageDataObject.CardDAV2Object = this;
+       PageDataObject.ConnectionSessionObject = ConnectionSession;
+       PageDataObject.DataSetting = &PageData;
+       PageDataObject.ServerUsingSSL = false;
+
+       PageHeaderObject.CardDAV2Object = this;
+       PageHeaderObject.ConnectionSessionObject = ConnectionSession;
+       PageHeaderObject.DataSetting = &PageHeader;
+       PageHeaderObject.ServerUsingSSL = false;
+       
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddress.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);
+       curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
+       curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
+       curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageDataObject);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeaderObject);
+       curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1L);
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
+
+       if (DoAuthentication == true){
+               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+       } else {
+               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, NULL);             
+       }
+       
+}
+
+void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
+       
+       // Setup the default parameters.
+       
+       string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
+       string UsernamePassword = ServerUser + ":" + ServerPass;
+
+       PageDataObject.CardDAV2Object = this;
+       PageDataObject.ConnectionSessionObject = ConnectionSession;
+       PageDataObject.DataSetting = &PageData;
+       PageDataObject.ServerUsingSSL = true;
+
+       PageHeaderObject.CardDAV2Object = this;
+       PageHeaderObject.ConnectionSessionObject = ConnectionSession;
+       PageHeaderObject.DataSetting = &PageHeader;
+       PageHeaderObject.ServerUsingSSL = true;
+       
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
+       curl_easy_setopt(ConnectionSession, CURLOPT_CERTINFO, 1L);
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);
+       curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
+       curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, 0L);
+       curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageDataObject);
+       curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeaderObject);
+       curl_easy_setopt(ConnectionSession, CURLOPT_ERRORBUFFER, SessionErrorBuffer);
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
+
+       if (DoAuthentication == true){
+               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+       } else {
+               curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, NULL);             
+       }
+       
+       if (EnableSSLBypass == true){
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 0L);
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 0L);
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYSTATUS, 0L);
+       } else {
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 2L);
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 1L);
+               curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYSTATUS, 1L);
+       }
+       
+#if !defined(__APPLE__) || defined(__WIN32__)
+       
+       if (TestMode == false && ServerAccount.size() > 0){
+               
+               // Check if the server certificate file exists.
+               
+               string CertificateFilename = GetAccountDir(ServerAccount, true);
+               
+               if (wxFile::Exists(CertificateFilename)){
+               
+                       curl_easy_setopt(ConnectionSession, CURLOPT_CAINFO, CertificateFilename.c_str());
+                       
+                       // Force CURLOPT_SSL_VERIFYSTATUS to 0.
+                       curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYSTATUS, 0L);
+                       
+               }
+               
+       }
+
+#endif
+       
+}
+
+string CardDAV2::BuildURL(string URI){
+       
+       string ServerAddressURL;
+       
+       if (ServerSSL == true){
+               ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;      
+       } else {
+               ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + URI;
+       }
+       
+       return ServerAddressURL;
+       
+}
+
+string CardDAV2::GetErrorMessage(){
+       
+       ErrorMessage = SessionErrorBuffer;      
+       return ErrorMessage;
+       
+}
+
+void CardDAV2::ResetResults(){
+       
+       SSLStatus = false;
+       COSSLVerified SSLVerified = COSSL_NORESULT;
+       ValidResponse = false;
        AuthPassed = false;
        CanProcess = false;
        SSLSelfSigned = false;
        TaskCompleted = false;
        ErrorMessage = "";
        SessionErrorBuffer[0] = '\0';
+       SessionResult = CURLE_OK;
        PageData = "";
        PageHeader = "";
        if (HeaderList != nullptr){
@@ -995,6 +1547,150 @@ void CardDAV2::ResetResults(){
        
 }
 
+string CardDAV2::GetETagValue(){
+       
+       xmlDocPtr xmlCardDAVDoc;
+
+       xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+
+       xmlNodePtr nodeLevel1;
+       xmlNodePtr nodeLevel2;
+       xmlNodePtr nodeLevel3;
+       xmlNodePtr nodeLevel4;
+       xmlNodePtr nodeLevel5;
+       xmlNodePtr nodeLevel6;
+
+       //std::map<wxString,wxString> xmlDataMap;
+
+       std::string DataFilename;
+       std::string ETagData;
+
+       std::string xmlStringSafe;
+       std::string ETagValue;
+
+       // 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().ToStdString();
+                                                       
+                                                       }
+                                                       
+                                                       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 = (const char*)nodeLevel6->content;
+                                                                               if (ETagData[0] == '"' && ETagData[(ETagData.size() - 1)] == '"'){
+                                                       
+                                                                                       ETagData.erase(0, 1);
+                                                                                       ETagData.erase((ETagData.size() - 1));
+                                                       
+                                                                               }
+                                                                       
+                                                                               ETagFound = TRUE;
+
+                                                                       }
+                                                                       
+                                                               }
+
+                                                       }       
+
+                                       }
+
+                               }
+
+                       }
+
+               }
+               
+               if (HREFFound == TRUE && ETagFound == TRUE){
+                               
+                       // Add to the map data.
+                               
+                       ETagValue = ETagData;
+                       
+                       HREFFound = FALSE;
+                       ETagFound = FALSE;
+                       break;
+                               
+               }
+
+
+       }
+
+       xmlFreeDoc(xmlCardDAVDoc);
+       
+       return ETagValue;
+       
+}
+
 string CardDAV2::GetETagHeader(){
        
        // Go through each of the lines looking for the
@@ -1157,4 +1853,163 @@ vector<string> CardDAV2::GetDAVHeader(){
        
        return DAVHeaderList;
        
-}
\ No newline at end of file
+}
+
+void CardDAV2::ProcessContactData(COContactList *ContactList){
+       
+       xmlDocPtr xmlCardDAVDoc;
+       xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+
+       xmlNodePtr MultiStatusNode;
+       xmlNodePtr ResponseNode;
+       xmlNodePtr ResponseDataNode;
+       xmlNodePtr PropStatNode;
+       xmlNodePtr ValueNode;
+       xmlNodePtr ETagNode;
+       xmlNodePtr StatusNode;
+
+       std::string HREFValue;
+       std::string ETagValue;
+       std::string StatusValue;
+       std::string SyncValue;
+
+       // Go through the document!
+
+       MultiStatusNode = xmlCardDAVDoc->children;
+
+       if (MultiStatusNode == nullptr){
+               return;
+       }
+
+       bool SyncTokenFound = false;
+
+       // Tranverse through the catacombs of the response to get our ETag for the file and
+       // the server syncronisation token.
+       
+       for (ResponseNode = MultiStatusNode->children;
+               ResponseNode != nullptr;
+               ResponseNode = ResponseNode->next){
+
+               // Check if tag is response or sync-token.
+
+               if (!xmlStrcmp(ResponseNode->name, (const xmlChar *)"response") ||
+               !xmlStrcmp(ResponseNode->name, (const xmlChar *)"d:response") ||
+               !xmlStrcmp(ResponseNode->name, (const xmlChar *)"D:response")){
+
+                       COContactStatus ContactStatus = COCS_UNKNOWN;
+                       
+                       for (ResponseDataNode = ResponseNode->children;
+                               ResponseDataNode != nullptr;
+                               ResponseDataNode = ResponseDataNode->next){
+
+                               if (!xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"href") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"d:href") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"D:href")){
+                               
+                                       HREFValue = (const char*)ResponseDataNode->children->content;
+
+                                       // Get the filename after the last forward slash.
+                                       
+                                       int LastSlash = 0;
+                                       
+                                       for (int HREFValueSeek = 0; HREFValueSeek < HREFValue.size(); HREFValueSeek++){
+                                               
+                                               if (HREFValue[HREFValueSeek] == '/'){
+                                               
+                                                       LastSlash = HREFValueSeek;
+                                                       
+                                               }
+                                               
+                                       }
+                                       
+                                       HREFValue = HREFValue.substr((LastSlash + 1));
+                                       
+                               } else if (!xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"propstat") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"d:propstat") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"D:propstat")){
+
+                                       for (PropStatNode = ResponseDataNode->children;
+                                               PropStatNode != nullptr;
+                                               PropStatNode = PropStatNode->next){
+
+                                               if (!xmlStrcmp(PropStatNode->name, (const xmlChar *)"prop") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"d:prop") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"D:prop")){
+
+                                                       for (ETagNode = PropStatNode->children;
+                                                               ETagNode != nullptr;
+                                                               ETagNode = ETagNode->next){
+
+                                                                       if (!xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag") ||
+                                                                       !xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag") ||
+                                                                       !xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag")){
+
+                                                                               ETagValue = (const char*)ETagNode->children->content;
+
+                                                                               if (ETagValue.size() > 2 && ETagValue.substr(0,1) == "\""){
+                                                                                       ETagValue.erase((ETagValue.size() - 1),1);
+                                                                                       ETagValue.erase(0,1);
+                                                                               }
+
+                                                                       }
+                                                       
+
+                                                       }
+
+                                               } else if (!xmlStrcmp(PropStatNode->name, (const xmlChar *)"status") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"d:status") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"D:status")){
+
+                                                       StatusValue = (const char*)PropStatNode->children->content;
+
+                                                       if (StatusValue == "HTTP/1.1 200 OK"){
+
+                                                               ContactStatus = COCS_UPDATED;
+
+                                                       } else if (StatusValue == "HTTP/1.1 404 Not Found"){
+
+                                                               ContactStatus = COCS_DELETED;
+
+                                                       } else {
+
+                                                               ContactStatus = COCS_UNKNOWN;
+
+                                                       }
+
+                                               }
+
+                                       }
+
+                               }
+
+                       }
+
+                       COContactData ContactInformation;
+                       
+                       ContactInformation.Location = HREFValue;
+                       ContactInformation.Data = ETagValue;
+                       ContactInformation.Status = ContactStatus;
+
+                       HREFValue.clear();
+                       ETagValue.clear();
+                       StatusValue.clear();
+                       
+                       ContactList->ListData.push_back(ContactInformation);
+
+               } else if (!xmlStrcmp(ResponseNode->name, (const xmlChar *)"sync-token") ||
+                       !xmlStrcmp(ResponseNode->name, (const xmlChar *)"d:sync-token") ||
+                       !xmlStrcmp(ResponseNode->name, (const xmlChar *)"D:sync-token")){
+
+                       SyncValue = (const char*)ResponseNode->children->content;
+
+               }
+
+       }
+
+       ContactList->SyncToken = SyncValue;
+
+       xmlFreeDoc(xmlCardDAVDoc);
+
+       return;
+       
+}
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy