Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
CalDAV: Implemented Win32 support
[xestiacalendar/.git] / source / objects / CalDAV / CalDAV.cpp
index d9d81e4..48fdb74 100644 (file)
@@ -1,14 +1,14 @@
 // CalDAV.cpp - CalDAV Connection Object.
 //
-// (c) 2016 Xestia Software Development.
+// (c) 2016-2017 Xestia Software Development.
 //
 // This file is part of Xestia Calendar.
 //
-// Xestia Address Book is free software: you can redistribute it and/or modify
+// Xestia Calendar is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by the
 // Free Software Foundation, version 3 of the license.
 //
-// Xestia Address Book is distributed in the hope that it will be useful,
+// Xestia Calendar is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 // GNU General Public License for more details.
 
 using namespace std;
 
-size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer)
+size_t CalDAV::CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, void *stream)
 {
        
-       string ReceivedBufferString = "";
-       ReceivedBufferString.append(ReceivedBuffer, NewMemoryBytes);
-       
-       StringPointer->append(ReceivedBufferString);
-       
-       return Size * NewMemoryBytes;
+       // Writeback function for the CardDAV object.
+
+       CalDAVPassObject *data = static_cast<CalDAVPassObject*>(stream);
+       data->DataSetting->append(receivedBuffer);
+
+       // Get the SSL engine pointer and trust if required on certain operating systems.
+
+       if (data->ServerUsingSSL == true) {
+
+#if defined(__APPLE__)
+
+               const struct curl_tlssessioninfo *TLSInfo;
+               CURLcode TLSCode;
+               TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo);
+
+               SecTrustRef CertificateData;
+
+               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) {
+                       SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &CertificateData);
+                       data->SSLContext = CertificateData;
+               }
+
+#elif defined(__WIN32__)
+
+               const struct curl_tlssessioninfo *TLSInfo;
+               CURLcode TLSCode;
+               TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo);
+
+               if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) {
+
+                       // Free the previous certificate data.
+
+                       //CertFreeCertificateContext(CertificateData);
+
+                       PCCERT_CONTEXT CertificateData;
+
+                       PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
+                       SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
+
+                       data->SSLContext = CertificateData;
+
+               }
+
+#endif
+
+       }
+
+       return size * newMemoryBytes;
        
 }
 
-size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){
+size_t CalDAVSend(char *sendBuffer, size_t size, size_t newMemoryBytes, void *dataStruct){
 
-       struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct;
+       struct CalDAVSendData *uploadPtr = (struct CalDAVSendData *)dataStruct;
        
-       if (UploadPtr->sizeleft){
+       if (uploadPtr->sizeleft){
 
-               UploadPtr->sizeleft--;
-               char CharSend;
+               uploadPtr->sizeleft--;
+               char charSend;
 
-               CharSend = (*UploadPtr->readptr)[UploadPtr->seek];
+               charSend = (*uploadPtr->readptr)[uploadPtr->seek];
                
-               *SendBuffer = CharSend;
+               *sendBuffer = charSend;
                
-               UploadPtr->seek++;
+               uploadPtr->seek++;
 
                return 1;
 
@@ -60,7 +102,7 @@ CalDAV::CalDAV(){
        // Setup the objects within the CalDAV connection 
        // object.
        
-       ConnectionHandle = curl_easy_init();
+       connectionHandle = curl_easy_init();
        
 }
 
@@ -69,22 +111,22 @@ CalDAV::~CalDAV(){
        // Destory the objects within the CalDAV connection
        // object.
        
-       curl_easy_cleanup(ConnectionHandle);
-       ConnectionHandle = nullptr;
+       curl_easy_cleanup(connectionHandle);
+       connectionHandle = nullptr;
        
 }
 
-void CalDAV::SetupConnectionData(CalDAVConnectionData *ConnData){
+void CalDAV::SetupConnectionData(CalDAVConnectionData *connData){
        
        // Check if ConnData is a nullptr, return if it is.
        
-       if (ConnData == nullptr){
+       if (connData == nullptr){
                return;
        }
        
        // Set the connection settings to the values from ConnData.
 
-       ConnectionData = (*ConnData);
+       connectionData = (*connData);
        
 }
 
@@ -93,104 +135,182 @@ CalDAVStatus CalDAV::GetConnectionData(){
        // Get the current connection settings for the CalDAV
        // connection object and return a CalDAVStatus object.
        
-       CalDAVStatus ConnectionStatus;
+       CalDAVStatus connectionStatus;
        
-       ConnectionStatus.Hostname = ConnectionData.Hostname;
-       ConnectionStatus.Port = ConnectionData.Port;
-       ConnectionStatus.Username = ConnectionData.Username;
-       ConnectionStatus.Prefix = ConnectionData.Prefix;
-       ConnectionStatus.UseSSL = ConnectionData.UseSSL;
-       ConnectionStatus.Timeout = ConnectionData.Timeout;
+       connectionStatus.hostname = connectionData.hostname;
+       connectionStatus.port = connectionData.port;
+       connectionStatus.username = connectionData.username;
+       connectionStatus.prefix = connectionData.prefix;
+       connectionStatus.useSSL = connectionData.useSSL;
+       connectionStatus.timeout = connectionData.timeout;
        
-       return ConnectionStatus;
+       return connectionStatus;
        
 }
 
-CalDAVServerResult CalDAV::Connect(){
+CalDAVServerResult CalDAV::Connect(bool doAuthentication){
 
-       CalDAVServerResult ServerResult;
+       connectionData.useSSL ? SetupDefaultParametersSSL(doAuthentication) : SetupDefaultParametersNonSSL(doAuthentication);
+       ResetResults();
 
-       string ServerAddress = "";
-       string ServerUserPass = "";
+       CalDAVServerResult serverResult;
+
+       string serverAddress = "";
+       string serverUserPass = "";
 
        // Setup the server address.
        
-       ServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+       serverAddress = BuildServerAddress(&connectionData, "/principals/");
 
        // Setup the server password.
        
-       ServerUserPass += ConnectionData.Username;
-       ServerUserPass += ":";
-       ServerUserPass += ConnectionData.Password;
-       
-       curl_easy_setopt(ConnectionHandle, CURLOPT_URL, ServerAddress.c_str());
-       curl_easy_setopt(ConnectionHandle, CURLOPT_USERPWD, ServerUserPass.c_str());
-       curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
-       curl_easy_setopt(ConnectionHandle, CURLOPT_FAILONERROR, 1L);
-       curl_easy_setopt(ConnectionHandle, CURLOPT_TIMEOUT, ConnectionData.Timeout);
-       curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVOutput);
-       curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEDATA, &ServerData);
-       curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEHEADER, &ServerHeader);
+       serverUserPass += connectionData.username;
+       serverUserPass += ":";
+       serverUserPass += connectionData.password;
+
+       PageDataObject.CalDAVObject = this;
+       PageDataObject.ConnectionSessionObject = connectionHandle;
+       PageDataObject.DataSetting = &serverData;
+       PageDataObject.ServerUsingSSL = true;
+
+       PageHeaderObject.CalDAVObject = this;
+       PageHeaderObject.ConnectionSessionObject = connectionHandle;
+       PageHeaderObject.DataSetting = &serverHeader;
+       PageHeaderObject.ServerUsingSSL = true;
+
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, serverUserPass.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, connectionData.timeout);
+       curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, CalDAV::CalDAVReceive);
+       curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &PageDataObject);
+       curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &PageHeaderObject);
        
        // Connect to the CalDAV server.
        
-       ServerResult.Code = curl_easy_perform(ConnectionHandle);
+       serverResult.code = curl_easy_perform(connectionHandle);
 
        // Process the result received from the server.
+
+       // Get the HTTP code.
        
-       if (ServerResult.Code != CURLE_OK){
-               
-               ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
-               
-       } else {
-               
-               ServerResult.Result = CALDAVQUERYRESULT_OK;
-               
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+
+       switch(serverResult.code){
+               case CURLE_OK:
+                       authPassed = true;
+               case CURLE_HTTP_RETURNED_ERROR:
+                       if (connectionData.useSSL)
+                       {
+                               sslStatus = connectionData.useSSL;
+                               sslVerified = COSSL_VERIFIED;
+                       }
+                       serverResult.result = CALDAVQUERYRESULT_OK;
+                       if (serverResult.httpCode == 401)
+                       {
+                               authPassed = false;
+                       }
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       if (connectionData.useSSL)
+                       {
+                               sslStatus = connectionData.useSSL;
+                               sslVerified = COSSL_UNABLETOVERIFY;
+                       }
+                       serverResult.result = CALDAVQUERYRESULT_SSLFAILURE;
+                       authPassed = false;
+                       break;
+               default:
+                       serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
+                       authPassed = false;
+                       break;
+       };
+
+       // Set the certificate data (if required).
+
+#if defined(__APPLE__)
+
+       if (connectionData.useSSL) {
+
+               certificateData = PageHeaderObject.SSLContext;
+
+       }
+
+#elif defined(__WIN32__)
+
+       if (connectionData.useSSL) {
+
+               certificateData = PageHeaderObject.SSLContext;
+
+       }
+
+#endif
+
+       // Check if a valid response was received before continuing.
+
+       if (serverResult.httpCode >= 200 && serverResult.httpCode <= 299)
+       {
+               validResponse = true;
        }
        
-       // Get the HTTP code.
+       return serverResult;
        
-       curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+}
+
+CalDAVServerResult CalDAV::GetServerResult(){
        
-       return ServerResult;
+       return connectionServerResult;
        
 }
 
 CalDAVServerSupport CalDAV::GetServerSupport(){
 
-       CalDAVServerSupport ServerStatus;
+       CalDAVServerSupport serverStatus;
        
        // Setup the server connection.
        
-       curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
        
-       CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+       // Set the results.
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
        
-       if (ServerResult != CURLE_OK){
-               return ServerStatus;
+       if (serverResult != CURLE_OK){
+               return serverStatus;
        }
        
        // Check that the server header has data in,
        // otherwise return an "empty" CalDAVServerSupport.
        
-       if (ServerHeader.size() == 0){
-               return ServerStatus;
+       if (serverHeader.size() == 0){
+               return serverStatus;
        }
        
        // Process each line looking for the first DAV header 
        // line.
        
-       bool NewlineMode = true;
+       bool newlineMode = true;
        
-       string DAVLine;
+       string davLine;
        
-       for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){
+       for (int charSeek = 0; charSeek < serverHeader.size(); charSeek++){
                
-               if (NewlineMode == true){
+               if (newlineMode == true){
                        
                        // Check if we have reached the end of the string.
                        
-                       if (CharSeek >= ServerHeader.size()){
+                       if (charSeek >= serverHeader.size()){
                                
                                break;
                                
@@ -199,29 +319,29 @@ CalDAVServerSupport CalDAV::GetServerSupport(){
                        // Check the first four letters to make sure
                        // they are 'DAV:'.
                        
-                       string DAVHeaderCheck = "";
+                       string davHeaderCheck = "";
                        
                        try {
-                               DAVHeaderCheck = ServerHeader.substr(CharSeek, 4);
+                               davHeaderCheck = serverHeader.substr(charSeek, 4);
                        }
                        
                        catch (out_of_range &oor){
                                break;
                        }
                        
-                       if (DAVHeaderCheck == "DAV:"){
+                       if (davHeaderCheck == "DAV:"){
                                
-                               CharSeek += 5;
+                               charSeek += 5;
                                
-                               for (; CharSeek < ServerHeader.size(); CharSeek++){
+                               for (; charSeek < serverHeader.size(); charSeek++){
                                        
-                                       if (ServerHeader[CharSeek] == '\n'){
+                                       if (serverHeader[charSeek] == '\n'){
                                        
                                                break;
                                                
                                        }
                                        
-                                       DAVLine.push_back(ServerHeader[CharSeek]);
+                                       davLine.push_back(serverHeader[charSeek]);
                                        
                                }
                                
@@ -229,13 +349,13 @@ CalDAVServerSupport CalDAV::GetServerSupport(){
                                
                        }
                        
-                       NewlineMode = false;
+                       newlineMode = false;
                        
                }
                
-               if (ServerHeader[CharSeek] == '\n'){
+               if (serverHeader[charSeek] == '\n'){
                        
-                       NewlineMode = true;
+                       newlineMode = true;
                        
                }
                
@@ -243,131 +363,1531 @@ CalDAVServerSupport CalDAV::GetServerSupport(){
        
        // Process the DAV line.
        
-       vector<string> DAVLineData;
-       string DAVSegmentString;
+       vector<string> davLineData;
+       string davSegmentString;
        
-       for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){
+       for (int charSeek = 0; charSeek < davLine.size(); charSeek++){
                
-               if (DAVLine[CharSeek] == ' '){
+               if (davLine[charSeek] == ' '){
                        continue;
                }
                
-               if (DAVLine[CharSeek] == ','){
+               if (davLine[charSeek] == ','){
                        
-                       DAVLineData.push_back(DAVSegmentString);
-                       DAVSegmentString.clear();
+                       davLineData.push_back(davSegmentString);
+                       davSegmentString.clear();
                        continue;
                        
                }
                
-               DAVSegmentString += DAVLine[CharSeek];
+               davSegmentString += davLine[charSeek];
                
        }
        
        // Process the DAV values and set each value
        // to true as required.
        
-       for (int DAVItemSeek = 0; 
-               DAVItemSeek < DAVLineData.size();
-               DAVItemSeek++){
+       for (int davItemSeek = 0; 
+               davItemSeek < davLineData.size();
+               davItemSeek++){
                        
-               if (DAVLineData.at(DAVItemSeek) == "calendar-access"){
+               if (davLineData.at(davItemSeek) == "calendar-access"){
                        
-                       ServerStatus.BasicSupport = true;
+                       serverStatus.basicSupport = true;
                
                }
                        
        }
        
-       return ServerStatus;
+       // Reset the connection status.
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+       
+       return serverStatus;
        
 }
 
-bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){
-
-       // Check if the passed CalDAV Connection Data is has
-       // an address set. Return false if nullptr is used.
+string CalDAV::GetUserPrincipal(){
+       
+       string currentUserPrincipal = "";
+       string userPrincipalRequest = "";
+       CalDAVSendData userPrincipalSendData;
+       
+       userPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<d:propfind xmlns:d=\"DAV:\">\n"
+       " <d:prop>\n"
+       "  <d:current-user-principal />\n"
+       " </d:prop>\n"
+       "</d:propfind>";
+       
+       userPrincipalSendData.readptr = &userPrincipalRequest;
+       userPrincipalSendData.sizeleft = userPrincipalRequest.size();
+       
+       // Setup the header.
+       
+       struct curl_slist *userPrincipalRequestHeader = NULL;
+       
+       userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Depth: 0");
+       userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Prefer: return-minimal");
+       userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, userPrincipalRequestHeader);
 
-       if (ConnData == nullptr){
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &userPrincipalSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
        
-               return false;
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
        
+       // Set the results.
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
        }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
        
-       // Check the server hostname. Return false
-       // if no value has been set.
+       if (serverResult != CURLE_OK){
+               
+               return currentUserPrincipal;
+               
+       }
+       
+       // Process the User Principal from the ServerData.
+
+       currentUserPrincipal = ProcessXMLUserPrincipal();
        
-       if (ConnData->Hostname.size() == 0){
+       // Reset the changed settings.
        
-               return false;
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+
+       return currentUserPrincipal;
+
+}
+
+string CalDAV::GetCalendarHome(string userPrincipalURI){
+       
+       string calendarHomeURI = "";
+
+       // Build the Calendar Home URL address.
+       
+       string calendarHomeURL = BuildServerAddress(&connectionData, userPrincipalURI);
+       
+       // Setup the header request.
+       
+       CalDAVSendData calendarHomeSendData;
+       
+       string calendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+       " <d:prop>\n"
+       "  <c:calendar-home-set />\n"
+       " </d:prop>\n"
+       "</d:propfind>";
        
+       calendarHomeSendData.readptr = &calendarHomeRequest;
+       calendarHomeSendData.sizeleft = calendarHomeRequest.size();
+       
+       // Setup the header.
+       
+       struct curl_slist *calendarRequestHeader = NULL;
+       
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Depth: 0");
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Prefer: return-minimal");
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarHomeURL.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarHomeSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
+       
+       // Set the results.
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
        }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
        
-       // Check the server port. Return false if
-       // no value has been set or the port number
-       // is less than 1 or higher than 65535.
+       if (serverResult != CURLE_OK){
+               
+               return calendarHomeURI;
+               
+       }
        
-       if (ConnData->Port < 1 || ConnData->Port > 65535){
+       // Process the User Principal from the ServerData.
+
+       calendarHomeURI = ProcessXMLCalendarHome();
        
-               return false;
+       // Reset the changed settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return calendarHomeURI;
+       
+}
+
+CalDAVCalendarList CalDAV::GetCalendars(){
        
+       CalDAVCalendarList serverList;
+       CalDAVSendData calendarListSendData;
+       
+       // Build the server address.
+       
+       string userPrincipalURI = "";
+       userPrincipalURI = GetUserPrincipal();
+       
+       if (userPrincipalURI.size() == 0){
+               
+               return serverList;
+               
        }
        
-       // Check the server username. Return false
-       // if no value has been set.
+       string calendarHomeURI = "";
+       calendarHomeURI = GetCalendarHome(userPrincipalURI);
+       
+       string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURI);
        
-       if (ConnData->Username.size() == 0){
+       string calendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:prop>\n"
+        "  <d:resourcetype />\n"
+       "  <d:displayname />\n"
+       "  <d:sync-token />\n"
+       "  <x0:calendar-color />\n"
+       "  <x0:calendar-order />\n"
+       "  <cs:getctag />\n"
+       "  <c:supported-calendar-component-set />\n"
+       "  <c:calendar-description />\n"
+       " </d:prop>\n"
+       "</d:propfind>";
+       
+       calendarListSendData.readptr = &calendarListRequest;
+       calendarListSendData.sizeleft = calendarListRequest.size();
+       
+       // Setup the header.
+       
+       struct curl_slist *calendarListRequestHeader = NULL;
+       
+       calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Depth: 1");
+       calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Prefer: return-minimal");
+       calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarListRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarListSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
+       
+       //ServerList = ProcessXMLCalendarList();
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+       
+       if (serverResult != CURLE_OK){
                
-               return false;
+               return serverList;
                
-       }       
+       }
        
-       // Check the server password. Return false
-       // if no value has been set.
+       // Process the received XML data into a list of calendars
+       // and locations.
+       
+       serverList = ProcessXMLCalendarList();
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return serverList;
+       
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF){
        
-       if (ConnData->Password.size() == 0){
+       CalDAVEntryList entryList;
+       CalDAVSendData entryListSendData;
+       
+       if (calendarHREF->size() == 0){
                
-               return false;
+               return entryList;
                
        }
+       
+       string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
+       
+       string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+       
+       /*if (CalendarTag == nullptr){*/
+               
+       entryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       "  <c:calendar-data />\n"
+       " </d:prop>\n"
+       " <c:filter>\n"
+       "  <c:comp-filter name=\"VCALENDAR\" />\n"
+       " </c:filter>\n"
+       "</c:calendar-query>";
+               
+       /*} else {
 
-       // Cannot check UseSSL: It is either true
-       // or false.
+               EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+               " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"          
+               " <d:sync-token>";
+               EntryListRequest += *CalendarTag;
+               EntryListRequest += "</d:sync-token>\n"
+               " <d:sync-level>1</d:sync-level>\n"
+               " <d:prop>\n"
+               "  <d:getetag />\n"
+               "  <c:calendar-data />\n"
+               " </d:prop>\n"
+               "</d:sync-collection>";
+               
+       }*/
        
-       // Cannot check Prefix: The prefix may need
-       // to be worked out first.
+       entryListSendData.readptr = &entryListRequest;
+       entryListSendData.sizeleft = entryListRequest.size();
+       
+       struct curl_slist *entryListRequestHeader = NULL;
+       
+       entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       /*if (CalendarTag != nullptr){
+       
+               EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+               EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+               
+       }*/
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
+       
+       //ServerList = ProcessXMLCalendarList();
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+       
+       if (serverResult != CURLE_OK){
+               
+               return entryList;
+               
+       }
+       
+       // Process the received XML data into a list of calendars
+       // and locations.
+       
+       entryList = ProcessXMLEntryList();
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return entryList;
+       
+}
 
-       // No errors were found whilst checking so
-       // return true.
+CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF, string *calendarTag){
        
-       return true;
+       CalDAVEntryList entryList;
+       CalDAVSendData entryListSendData;
+       
+       if (calendarHREF->size() == 0){
+               
+               return entryList;
+               
+       }
+       
+       string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
+       
+       // First query: Get the list of contacts that need to be updated.
+       
+       string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 
-}
+       entryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:sync-token>";
+       
+       if (calendarTag != nullptr){
+       
+               entryListRequest += *calendarTag;
+               
+       } else {
+       
+               entryListRequest += "";
+               
+       }
 
-string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){
+       entryListRequest += "</d:sync-token>\n"
+       " <d:sync-level>1</d:sync-level>\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       " </d:prop>\n"
+       "</d:sync-collection>";
        
-       string ServerAddress;
+       entryListSendData.readptr = &entryListRequest;
+       entryListSendData.sizeleft = entryListRequest.size();
        
-       // Setup the server address.
+       struct curl_slist *entryListRequestHeader = NULL;
+       
+       entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
        
-       if (ConnData->UseSSL == true){
-               ServerAddress += "https://";
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverResult = curl_easy_perform(connectionHandle);
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
        } else {
-               ServerAddress += "http://";
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+       
+       if (serverResult != CURLE_OK){
+               
+               return entryList;
+               
        }
        
-       ServerAddress += ConnData->Hostname;
+       entryList = ProcessXMLSyncTokenList();
        
-       // Check if server port is 80, otherwise
-       // specifiy the port number in the address.
+       // Check the last entry matches the HREF and if it 
+       // does then delete it.
+       
+       if (entryList.href.size() > 0) {
+       
+               if (entryList.href.rbegin()->second == *calendarHREF){
+                       
+                       entryList.href.erase((entryList.href.size() - 1));
+                       entryList.tag.erase((entryList.href.size() - 1));
+                       entryList.data.erase((entryList.href.size() - 1));
+               
+               }
+       
+       }
+       
+       // Build the list into a new list for getting the new 
+       // calendar data with.
+       
+       entryListRequest.clear();
+       
+       entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+       entryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
+       " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       "  <c:calendar-data />\n"
+       " </d:prop>\n";
+       
+       for (std::map<int,string>::iterator hrefIter = entryList.href.begin(); 
+               hrefIter != entryList.href.end(); hrefIter++){
+               
+               string entryListHREFString = hrefIter->second;
+                       
+               entryListRequest += " <d:href>";
+               entryListRequest += entryListHREFString;
+               entryListRequest += "</d:href>\n";
+                       
+       }
+       
+       entryListRequest += "</c:calendar-multiget>";
+       
+       CalDAVSendData updatedEntryListSendData;        
+       
+       updatedEntryListSendData.readptr = &entryListRequest;
+       updatedEntryListSendData.sizeleft = entryListRequest.size();
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &updatedEntryListSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
        
-       if (ConnData->Port != 80){
-               ServerAddress += ":";
-               ServerAddress += to_string(ConnData->Port);
+       // Get the updated calendar data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       entryList.href.clear();
+       entryList.tag.clear();
+       entryList.data.clear();
+       
+       serverResult = curl_easy_perform(connectionHandle);
+
+       // Check the last entry matches the HREF and if it 
+       // does then delete it.
+       
+       if (serverResult == CURLE_OK){
+               connectionServerResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
+       }
+       connectionServerResult.code = serverResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
+       
+       if (serverResult != CURLE_OK){
+               
+               return entryList;
+               
        }
        
-       ServerAddress += URIAddress;
+       entryList = ProcessXMLEntryList();
+       
+       // Second query: Get the list of contact data for the contacts that have
+       // beenchanged.
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
        
-       return ServerAddress;
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return entryList;
+       
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string calendarName){
+       
+       CalDAVServerResult serverResult;
+       
+       AddCalendar(&calendarName, nullptr);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string *calendarName, string *calendarShortName){
+       
+       CalDAVServerResult serverResult;
+       CalDAVSendData calendarAddSendData;
+       
+       // Build the server address.
+       
+       string userPrincipalURI = "";
+       userPrincipalURI = GetUserPrincipal();
+       
+       if (userPrincipalURI.size() == 0){
+               
+               return serverResult;
+               
+       }
+       
+       string calendarHomeURI = "";
+       calendarHomeURI = GetCalendarHome(userPrincipalURI);
+       
+       // Generate the UUID.
+       
+       string UUIDValue = "";
+       
+       if (calendarShortName == nullptr){
+       
+               UUIDValue = GenerateUUID();
+               UUIDValue.erase(UUIDValue.end()-1);
+
+       } else {
+       
+               UUIDValue = *calendarShortName;
+               
+       }
+               
+       string calendarHomeURL = calendarHomeURI;
+       calendarHomeURL.append(UUIDValue);
+       calendarHomeURL.append("/");
+       
+       // Build the calendar list address.
+       
+       string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURL);
+       
+       string calendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+       " <d:set>\n"
+       "  <d:prop>\n"
+       "   <d:displayname>";
+       calendarAddRequest += *calendarName;
+       calendarAddRequest += "</d:displayname>\n"
+       "   <c:supported-calendar-component-set>\n"
+       "    <c:comp name=\"VTODO\"/>\n"
+       "    <c:comp name=\"VEVENT\"/>\n"
+       "   </c:supported-calendar-component-set>\n"
+       "  </d:prop>\n"
+       " </d:set>\n"
+       "</c:mkcalendar>";
+       
+       calendarAddSendData.readptr = &calendarAddRequest;
+       calendarAddSendData.sizeleft = calendarAddRequest.size();
+       
+       // Setup the header.
+       
+       struct curl_slist *calendarRequestHeader = NULL;
+       
+       //curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarAddSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::EditCalendarProcess(string *calendarHREF,
+                       string *calendarName,
+                       Colour *calendarColour,
+                       string *calendarDescription,
+                       int *calendarOrder){
+
+       CalDAVServerResult serverResult;
+       CalDAVSendData calendarEditSendData;
+       
+       // Build the server address.
+       
+       string userPrincipalURI = "";
+       userPrincipalURI = GetUserPrincipal();
+       
+       if (userPrincipalURI.size() == 0){
+               
+               return serverResult;
+               
+       }
+       
+       string calendarHomeURI = "";
+       calendarHomeURI = GetCalendarHome(userPrincipalURI);
+       
+       // Generate the UUID.
+       
+       string UUIDValue = GenerateUUID();
+       UUIDValue.erase(UUIDValue.end()-1);
+       
+       string calendarHomeURL = calendarHomeURI;
+       calendarHomeURL.append(UUIDValue);
+       calendarHomeURL.append("/");
+       
+       // Build the calendar list address.
+       
+       string calendarEditURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
+       
+       string calendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
+       "       xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+       " <d:set>\n"
+       "  <d:prop>\n";
+       
+       // Update the calendar name.
+       
+       if (calendarName != nullptr){
+       
+               calendarEditRequest += "<d:displayname>";
+               calendarEditRequest += (*calendarName);
+               calendarEditRequest += "</d:displayname>\n";
+               
+       }
+       
+       // Update the calendar colour.
+       
+       if (calendarColour != nullptr){
+               
+               calendarEditRequest += "<x0:calendar-color>";
+               calendarEditRequest += (*calendarColour);
+               calendarEditRequest += "</x0:calendar-color>\n";
+               
+       }
+       
+       // Update the calendar description.
+       
+       if (calendarDescription != nullptr){
+               
+               calendarEditRequest += "<c:calendar-description>";
+               calendarEditRequest += (*calendarDescription);
+               calendarEditRequest += "</c:calendar-description>\n";           
+               
+       }
+       
+       // Update the calendar order.
+       
+       if (calendarOrder != nullptr){
+               
+               calendarEditRequest += "<x0:calendar-order>";
+               calendarEditRequest += to_string((*calendarOrder));
+               calendarEditRequest += "</x0:calendar-order>\n";
+               
+       }
+       
+       calendarEditRequest += "  </d:prop>\n"
+       " </d:set>\n"
+       "</d:propertyupdate>";
+       
+       calendarEditSendData.readptr = &calendarEditRequest;
+       calendarEditSendData.sizeleft = calendarEditRequest.size();
+       
+       // Setup the header.
+       
+       struct curl_slist *calendarRequestHeader = NULL;
+       
+       //curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarEditURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarEditSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       
+       return serverResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+                       string *calendarName,
+                       Colour *calendarColour,
+                       string *calendarDescription,
+                       int *calendarOrder){
+       
+       CalDAVServerResult serverResult;
+       
+       serverResult = EditCalendarProcess(calendarHREF,
+               calendarName,
+               calendarColour,
+               calendarDescription,
+               calendarOrder);
+                               
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+                       Colour *calendarColour){
+
+       CalDAVServerResult serverResult;
+
+       serverResult = EditCalendarProcess(calendarHREF,
+               nullptr,
+               calendarColour,
+               nullptr,
+               nullptr);
+                               
+       return serverResult;    
+       
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+                       string *calendarName){
+       
+       CalDAVServerResult serverResult;
+       
+       serverResult = EditCalendarProcess(calendarHREF,
+               calendarName,
+               nullptr,
+               nullptr,
+               nullptr);       
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
+                       int *calendarOrder){
+       
+       CalDAVServerResult serverResult;
+       
+       serverResult = EditCalendarProcess(calendarHREF,
+               nullptr,
+               nullptr,
+               nullptr,
+               calendarOrder);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::EditCalendarDescription(string *calendarHREF,
+                       string *calendarDescription){
+       
+       CalDAVServerResult serverResult;
+       
+       serverResult = EditCalendarProcess(calendarHREF,
+               nullptr,
+               nullptr,
+               calendarDescription,
+               nullptr);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::DeleteCalendar(string *calendarHREF){
+
+       CalDAVServerResult serverResult;
+       
+       // Build the server address.
+       
+       string userPrincipalURI = "";
+       userPrincipalURI = GetUserPrincipal();
+       
+       if (userPrincipalURI.size() == 0){
+               
+               return serverResult;
+               
+       }
+       
+       string calendarHomeURI = "";
+       calendarHomeURI = GetCalendarHome(userPrincipalURI);
+       
+       // Generate the UUID.
+       
+       string UUIDValue = GenerateUUID();
+       UUIDValue.erase(UUIDValue.end()-1);
+       
+       string calendarHomeURL = calendarHomeURI;
+       calendarHomeURL.append(UUIDValue);
+       calendarHomeURL.append("/");
+       
+       // Build the calendar list address.
+       
+       struct curl_slist *deleteRequestHeader = NULL;
+       
+       deleteRequestHeader = curl_slist_append(deleteRequestHeader, "Depth: infinity");
+       
+       string calendarDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, deleteRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarDeleteURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+       
+       // Delete the calendar.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::GetEntryETag(string *calendarEntryHREF, string *eTagValue){
+       
+       CalDAVServerResult serverResult;
+       CalDAVSendData entryETagGetData;
+       
+       // Build the server address.
+       
+       string userPrincipalURI = "";
+       userPrincipalURI = GetUserPrincipal();
+       
+       if (userPrincipalURI.size() == 0){
+               
+               return serverResult;
+               
+       }
+       
+       string calendarHomeURI = "";
+       calendarHomeURI = GetCalendarHome(userPrincipalURI);
+
+       // Split the path and filename.
+       
+       string entryURIPath;
+       string entryFilename;
+       
+       SplitPathFilename(calendarEntryHREF, &entryURIPath, &entryFilename);
+       
+       // Build the request for the server.
+
+       string entryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+       "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+       " <d:prop>\n"
+       "  <d:getetag />\n"
+       " </d:prop>\n"
+       " <d:href>";
+       entryETagRequest += (*calendarEntryHREF);
+       entryETagRequest += "</d:href>\n"
+       "</c:calendar-multiget>";
+       
+       entryETagGetData.readptr = &entryETagRequest;
+       entryETagGetData.sizeleft = entryETagRequest.size();
+       
+       // Build the calendar list address.
+       
+       struct curl_slist *getETagRequestHeader = NULL;
+
+       getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Depth: 1");     
+       getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Prefer: return-minimal");
+       getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
+       
+       string getETagURLAddress = BuildServerAddress(&connectionData, entryURIPath);
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, getETagRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, getETagURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryETagGetData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Attempt to get the entity tag.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       if (serverConnectionResult != CURLE_OK){
+               return serverResult;
+       }
+       
+       // Get the entity tag from the result.
+       
+       *eTagValue = ProcessXMLEntryETag();
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::AddEntry(string *calendarEntryHREF, string *entryData){
+       
+       // Add an entry to the calendar collection.
+       
+       CalDAVServerResult serverResult;
+       CalDAVSendData entryAddSendData;
+       
+       // Build the calendar list address.
+       
+       string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+       
+       entryAddSendData.readptr = entryData;
+       entryAddSendData.sizeleft = entryData->size();
+       
+       struct curl_slist *calendarRequestHeader = NULL;
+       
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::EditEntry(string *calendarEntryHREF, string *entryData, string *entryETag){
+       
+       // Edit an entry in the calendar collection.
+
+       // Add an entry to the calendar collection.
+       
+       CalDAVServerResult serverResult;
+       CalDAVSendData entryAddSendData;
+       
+       // Build the calendar list address.
+       
+       string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+       
+       entryAddSendData.readptr = entryData;
+       entryAddSendData.sizeleft = entryData->size();
+       
+       string ifMatchHeader = "If-Match: \"";
+       ifMatchHeader.append(*entryETag);
+       ifMatchHeader.append("\"");
+       
+       struct curl_slist *calendarRequestHeader = NULL;
+       
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+       calendarRequestHeader = curl_slist_append(calendarRequestHeader, ifMatchHeader.c_str());        
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+       
+       // Process the data.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return serverResult;
+       
+}
+
+CalDAVServerResult CalDAV::DeleteEntry(string *calendarEntryHREF){
+       
+       // Delete an entry in the calendar collection.
+       
+       CalDAVServerResult serverResult;
+       
+       // Build the calendar list address.
+       
+       string entryDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, entryDeleteURLAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+       
+       // Delete the calendar.
+       
+       serverData.clear();
+       serverHeader.clear();
+       
+       CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
+       
+       if (serverConnectionResult == CURLE_OK){
+               serverResult.result = CALDAVQUERYRESULT_OK;
+       } else {
+               serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
+       }
+       serverResult.code = serverConnectionResult;
+       curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
+       
+       // Restore the original settings.
+       
+       string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
+       curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
+       
+       return serverResult;
+       
+}
+
+COSSLVerified CalDAV::SSLVerify()
+{
+       return sslVerified;
+}
+
+void CalDAV::BypassSSLVerification(bool enableBypass){
+       enableSSLBypass = enableBypass;
+       sslSelfSigned = enableBypass;
+}
+
+#if defined(__APPLE__)
+
+SecTrustRef CalDAV::BuildSSLCollection(){
+       
+       return certificateData;
+       
+}
+
+#elif defined(__WIN32__)
+
+PCCERT_CONTEXT CalDAV::BuildSSLCollection(){
+
+       return certificateData;
+
+}
+
+#else
+
+SSLCertCollectionString CalDAV::BuildSSLCollection(){
+
+       // Build and return the SSL collection.
+       
+       SSLCertCollectionString sslCertInfo;
+
+       // Grab the certificate data.
+
+       union {
+               struct curl_slist *certdata;
+               struct curl_certinfo *certinfo;
+       } certptr;
+
+       certptr.certdata = NULL;
+       
+       CURLcode result = curl_easy_getinfo(connectionHandle, 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;
+               
+               for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
+                       
+                       // Using wxStringTokenizer from wxWidgets.
+                       
+                       wxStringTokenizer certDataInc(wxString::FromUTF8(slist->data), ":");
+                       
+                       // Get first token as the property name.
+                       
+                       certPropName = certDataInc.GetNextToken().ToStdString();
+                       
+                       // Get remaining tokens as the property value.
+                       
+                       while(certDataInc.HasMoreTokens()){
+                       
+                               certPropValue.append(certDataInc.GetNextToken());
+                       
+                       }
+                       
+                       sslCertDataInc.CertData.insert(std::make_pair(certPropName, certPropValue));
+                       certPropName.clear();
+                       certPropValue.clear();
+                       
+               }
+       
+               sslCertInfo.SSLCollection.insert(std::make_pair(i, sslCertDataInc));
+       
+       }
+       
+       return sslCertInfo;
+
+}
+
+#endif
+
+bool CalDAV::CanDoSSL(){
+       return sslStatus;
+}
+
+bool CalDAV::HasValidResponse(){
+       return validResponse;
+}
+
+bool CalDAV::AbleToLogin(){
+       return authPassed;
+}
+
+bool CalDAV::IsSelfSigned(){
+       return sslSelfSigned;
+}
+
+string CalDAV::GetErrorMessage(){
+       
+       errorMessage = sessionErrorBuffer;      
+       return errorMessage;
+       
+}
+
+static bool CalDAVObjectValidSettings(CalDAVConnectionData *connData){
+
+       // Check if the passed CalDAV Connection Data is has
+       // an address set. Return false if nullptr is used.
+
+       if (connData == nullptr){
+       
+               return false;
+       
+       }
+       
+       // Check the server hostname. Return false
+       // if no value has been set.
+       
+       if (connData->hostname.size() == 0){
+       
+               return false;
+       
+       }
+       
+       // Check the server port. Return false if
+       // no value has been set or the port number
+       // is less than 1 or higher than 65535.
+       
+       if (connData->port < 1 || connData->port > 65535){
+       
+               return false;
+       
+       }
+       
+       // Check the server username. Return false
+       // if no value has been set.
+       
+       if (connData->username.size() == 0){
+               
+               return false;
+               
+       }       
+       
+       // Check the server password. Return false
+       // if no value has been set.
+       
+       if (connData->password.size() == 0){
+               
+               return false;
+               
+       }
+
+       // Cannot check UseSSL: It is either true
+       // or false.
+       
+       // Cannot check Prefix: The prefix may need
+       // to be worked out first.
+
+       // No errors were found whilst checking so
+       // return true.
+       
+       return true;
+
+}
+
+string CalDAV::BuildServerAddress(CalDAVConnectionData *connData, string uriAddress){
+       
+       string serverAddress;
+       
+       // Setup the server address.
+       
+       if (connData->useSSL == true){
+               serverAddress += "https://";
+       } else {
+               serverAddress += "http://";
+       }
+       
+       serverAddress += connData->hostname;
+       
+       // Check if server port is 80, otherwise
+       // specifiy the port number in the address.
+       
+       if (connData->port != 80){
+               serverAddress += ":";
+               serverAddress += to_string(connData->port);
+       }
+       
+       serverAddress += uriAddress;
+       
+       return serverAddress;
+       
+}
+
+void CalDAV::SetupDefaultParametersNonSSL(bool doAuthentication){
+       
+       std::string serverAddress = "";
+
+       string serverAddressURL = "http://" + connectionData.hostname + ":" + to_string(connectionData.port) + "/";
+       string usernamePassword = connectionData.username + ":" + connectionData.password;
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddressURL.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_NOPROGRESS, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);
+       curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, 60);
+       curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, true);
+       curl_easy_setopt(connectionHandle, CURLOPT_USERAGENT, XSDCAL_USERAGENT);
+       curl_easy_setopt(connectionHandle, CURLOPT_NOSIGNAL, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "GET");
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_setopt(connectionHandle, CURLOPT_POSTFIELDS, nullptr);
+       curl_easy_setopt(connectionHandle, CURLOPT_POSTFIELDSIZE, 0L);
+
+       if (doAuthentication == true){
+               curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, usernamePassword.c_str());
+       } else {
+               curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, NULL);              
+       }
+       
+}
+
+void CalDAV::SetupDefaultParametersSSL(bool doAuthentication){
+       
+       // Setup the default parameters.
+       
+       string ServerAddressURL = "https://" + connectionData.hostname + ":" + to_string(connectionData.port) + "/";
+       string UsernamePassword = connectionData.username + ":" + connectionData.password;
+       
+       curl_easy_setopt(connectionHandle, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(connectionHandle, CURLOPT_NOPROGRESS, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_CERTINFO, 1L);
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);
+       curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, 60);
+       curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 0L);
+       curl_easy_setopt(connectionHandle, CURLOPT_USERAGENT, XSDCAL_USERAGENT);
+       curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer);
+       curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "GET");
+       curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, nullptr);
+       curl_easy_setopt(connectionHandle, CURLOPT_POSTFIELDS, nullptr);
+       curl_easy_setopt(connectionHandle, CURLOPT_POSTFIELDSIZE, 0L);
+
+       if (doAuthentication == true){
+               curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, UsernamePassword.c_str());
+       } else {
+               curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, NULL);              
+       }
+       
+       if (enableSSLBypass == true){
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 0L);
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 0L);
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYSTATUS, 0L);
+       } else {
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 2L);
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 1L);
+               curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYSTATUS, 1L);
+       }
+       
+#if !defined(__APPLE__) || defined(__WIN32__)
+       
+       if (connectionData.account.size() > 0){
+               
+               // Check if the server certificate file exists.
+               
+               string certificateFilename = GetAccountDir(connectionData.account, true);
+               
+               if (wxFile::Exists(certificateFilename)){
+                       
+                       curl_easy_setopt(connectionHandle, CURLOPT_CAINFO, certificateFilename.c_str());
+                       
+               }
+               
+       }
+
+#endif
+       
+}
+
+void CalDAV::ResetResults(){
+       
+       sslStatus = false;
+       COSSLVerified SSLVerified = COSSL_NORESULT;
+       validResponse = false;
+       authPassed = false;
+       sslSelfSigned = false;
+       //taskCompleted = false;
+       errorMessage = "";
+       sessionErrorBuffer[0] = '\0';
+       //sessionResult = CURLE_OK;
+       serverData = "";
+       serverHeader = "";
+       /*if (headerList != nullptr){
+               curl_slist_free_all(headerList);
+               headerList = nullptr;
+       }*/
        
 }
\ No newline at end of file
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