--- /dev/null
+// CardDAV2.cpp - CardDAV v2 class
+//
+// (c) 2012-2016 Xestia Software Development.
+//
+// This file is part of Xestia Address Book.
+//
+// Xestia Address Book 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,
+// 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
+
+#include "carddav2.h"
+
+#include <iostream>
+
+using namespace std;
+
+size_t CardDAV2::WritebackFunc(char *ptr, size_t size, size_t nmemb, void *stream){
+
+ return static_cast<CardDAV2*>(stream)->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);
+
+ // Get the SSL engine pointer and trust if required on certain operating systems.
+
+ if (ServerSSL){
+
+#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);
+ }
+
+#elif defined(__WIN32__)
+
+ 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){
+
+ // Free the previous certificate data.
+
+ CertFreeCertificateContext(CertificateData);
+
+ PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
+ SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
+
+ }
+
+#endif
+
+ }
+
+ return size * nmemb;
+
+}
+
+CardDAV2::~CardDAV2(){
+ curl_easy_cleanup(ConnectionSession);
+ ConnectionSession = nullptr;
+}
+
+#if defined(__APPLE__)
+
+#elif defined(__WIN32__)
+
+#else
+
+SSLCertCollectionString CardDAV2::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;
+
+ 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;
+
+ 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;
+
+}
+
+void CardDAV2::BypassSSLVerification(bool EnableBypass){
+ EnableSSLBypass = EnableBypass;
+ SSLSelfSigned = EnableBypass;
+}
+
+#endif
+
+void CardDAV2::SetupConnectionObject(){
+ ConnectionSession = curl_easy_init();
+}
+
+bool CardDAV2::IsTaskCompleted(){
+ return false;
+}
+
+COConnectResult CardDAV2::Connect(bool DoAuthentication){
+
+ ServerSSL ? SetupDefaultParametersSSL(DoAuthentication) : SetupDefaultParametersNonSSL(DoAuthentication);
+ ResetResults();
+
+ COConnectResult ConnectResult = COCONNECT_UNITTESTFAIL;
+ string ServerAddressURL = BuildURL("/principals/");
+
+ curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+
+ if (TestMode == true){
+ SessionResult = curl_easy_perform(ConnectionSession);
+ } else {
+
+ }
+
+ switch(SessionResult){
+ case CURLE_OK:
+ SSLStatus = true;
+ SSLVerified = COSSL_VERIFIED;
+ ConnectResult = COCONNECT_OK;
+ break;
+ case CURLE_SSL_CACERT:
+ case CURLE_SSL_CONNECT_ERROR:
+ SSLStatus = true;
+ ConnectResult = COCONNECT_OK;
+ SSLVerified = COSSL_UNABLETOVERIFY;
+ break;
+ default:
+ ConnectResult = COCONNECT_INVALID;
+ break;
+ };
+
+ // Check if an error occured before continuing.
+
+ // Check if authentication was successful.
+
+ long SessionResponseCode = 0;
+
+ curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+
+ if (DoAuthentication == true){
+
+ // Get the HTTP status code (Should be 200 and not 403).
+ // Return error otherwise.
+
+ if (SessionResponseCode == 200){
+ ConnectResult = COCONNECT_OK;
+ AuthPassed = true;
+ ValidResponse = true;
+ } else if (SessionResponseCode == 403){
+ ConnectResult = COCONNECT_AUTHFAIL;
+ AuthPassed = false;
+ ValidResponse = true;
+ } else if (SessionResponseCode >= 200) {
+ ConnectResult = COCONNECT_INVALID;
+ AuthPassed = false;
+ ValidResponse = true;
+ } else {
+ ConnectResult = COCONNECT_INVALID;
+ AuthPassed = false;
+ ValidResponse = false;
+ }
+
+ } else {
+
+ ValidResponse = true;
+
+ }
+
+ // Check the header to see if CardDAV is supported.
+
+ vector<string> DAVHeaderValues = GetDAVHeader();
+
+ for (vector<string>::iterator DAVHeaderValuesIter = DAVHeaderValues.begin();
+ DAVHeaderValuesIter != DAVHeaderValues.end(); DAVHeaderValuesIter++){
+
+ if ((*DAVHeaderValuesIter) == "addressbook"){
+ CanProcess = true;
+ break;
+ }
+
+ }
+
+ return ConnectResult;
+
+}
+
+COServerResponse CardDAV2::GetDefaultPrefix(string *ServerPrefix){
+
+ // 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();
+
+ // Need to do three requests:
+
+ // 1. Get the current user principal URI.
+ // 2. Get the address book home URI.
+ // 3. Get the default address book URI.
+
+ // Setup the first query finding out where the principal URL is.
+
+ const char* CurrentUserPrincipalXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+ "<D:propfind xmlns:D=\"DAV:\">\n"
+ " <D:prop>"
+ " <D:current-user-principal/>\n"
+ " </D:prop>"
+ "</D:propfind>";
+
+ // Setup the second query finding out where the address book home URL is.
+
+ const char* AddressBookHomeXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+ "<D:propfind xmlns:D=\"DAV:\""
+ " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+ " <D:prop>\n"
+ " <C:addressbook-home-set/>\n"
+ " </D:prop>\n"
+ "</D:propfind>";
+
+ // Setup the third query finding out where the default address book URL is.
+
+ const char* DefaultAddressBookXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+ "<D:propfind xmlns:D=\"DAV:\""
+ " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+ " <D:prop>\n"
+ " <C:default-addressbook-URL/>\n"
+ " </D:prop>\n"
+ "</D:propfind>";
+
+ string ServerAddressURL = BuildURL("/principals/");
+ curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+ curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, CurrentUserPrincipalXMLQuery);
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(CurrentUserPrincipalXMLQuery));
+
+ if (TestMode == true){
+ SessionResult = curl_easy_perform(ConnectionSession);
+ } else {
+
+ }
+
+ 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 == 207){
+ AuthPassed = true;
+ ValidResponse = true;
+ } else if (SessionResponseCode == 403){
+ AuthPassed = false;
+ ValidResponse = true;
+ } else if (SessionResponseCode >= 200) {
+ 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;
+ }
+
+ // Process the first response.
+
+ string UserPrincipalURI = GetUserPrincipalURI();
+
+ // Cleanup and reset for the second connection.
+
+ ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+ ResetResults();
+
+ ServerAddressURL = BuildURL(UserPrincipalURI);
+ curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+ curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, AddressBookHomeXMLQuery);
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(AddressBookHomeXMLQuery));
+
+ if (TestMode == true){
+ SessionResult = curl_easy_perform(ConnectionSession);
+ } else {
+
+ }
+
+ 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;
+ };
+
+ SessionResponseCode = 0;
+
+ curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+
+ if (SessionResponseCode == 200 || SessionResponseCode == 207){
+ //ConnectResult = COCONNECT_OK;
+ AuthPassed = true;
+ ValidResponse = true;
+ } else if (SessionResponseCode == 403){
+ //ConnectResult = COCONNECT_AUTHFAIL;
+ AuthPassed = false;
+ ValidResponse = true;
+ } else if (SessionResponseCode >= 200) {
+ //ConnectResult = COCONNECT_INVALID;
+ AuthPassed = false;
+ ValidResponse = true;
+ } else {
+ //ConnectResult = COCONNECT_INVALID;
+ 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;
+ }
+
+ // Process the second response.
+
+ string AddressBookHomeURI = GetAddressBookHomeURI();
+
+ // Cleanup and reset for the second connection.
+
+ ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+ ResetResults();
+
+ ServerAddressURL = BuildURL(AddressBookHomeURI);
+ curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+ curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, DefaultAddressBookXMLQuery);
+ curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(DefaultAddressBookXMLQuery));
+
+ if (TestMode == true){
+ SessionResult = curl_easy_perform(ConnectionSession);
+ } else {
+
+ }
+
+ 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;
+ };
+
+ SessionResponseCode = 0;
+
+ curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+
+ if (SessionResponseCode == 200 || SessionResponseCode == 207){
+ AuthPassed = true;
+ ValidResponse = true;
+ } else if (SessionResponseCode == 403){
+ AuthPassed = false;
+ ValidResponse = true;
+ } else if (SessionResponseCode >= 200) {
+ 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;
+ }
+
+ // Process the second response.
+
+ (*ServerPrefix) = GetDefaultAddressBookURI();
+
+ CanProcess = true;
+
+ ServerResponse.RequestResult = COREQUEST_OK;
+ ServerResponse.EntityTag = "";
+ ServerResponse.SessionCode = SessionResult;
+ ServerResponse.ResultCode = SessionResponseCode;
+ ServerResponse.ResultMessage = SessionErrorBuffer;
+ return ServerResponse;
+
+}
+
+std::string CardDAV2::GetUserPrincipalURI(){
+
+ xmlDocPtr xmlCardDAVDoc;
+ xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+ string UserPrincipalURI = "";
+
+ xmlNodePtr nodeLevel1;
+ xmlNodePtr nodeLevel2;
+ xmlNodePtr nodeLevel3;
+ xmlNodePtr nodeLevel4;
+ xmlNodePtr nodeLevel5;
+ xmlNodePtr nodeLevel6;
+ xmlNodePtr nodeLevel7;
+
+ for (nodeLevel1 = xmlCardDAVDoc->children;
+ nodeLevel1 != NULL;
+ nodeLevel1 = nodeLevel1->next)
+ {
+
+ for (nodeLevel2 = nodeLevel1->children;
+ nodeLevel2 != NULL;
+ nodeLevel2 = nodeLevel2->next)
+ {
+
+
+ for (nodeLevel3 = nodeLevel2->children;
+ nodeLevel3 != NULL;
+ nodeLevel3 = nodeLevel3->next)
+ {
+
+ for (nodeLevel4 = nodeLevel3->children;
+ nodeLevel4 != NULL;
+ nodeLevel4 = nodeLevel4->next)
+ {
+
+ for (nodeLevel5 = nodeLevel4->children;
+ nodeLevel5 != NULL;
+ nodeLevel5 = nodeLevel5->next)
+ {
+
+ for (nodeLevel6 = nodeLevel5->children;
+ nodeLevel6 != NULL;
+ nodeLevel6 = nodeLevel6->next)
+ {
+
+ if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+ ){
+
+ // Found the <href> part so extract the principal URL address.
+
+ for (nodeLevel7 = nodeLevel6->children;
+ nodeLevel7 != NULL;
+ nodeLevel7 = nodeLevel7->next)
+ {
+
+ UserPrincipalURI = ((const char*)nodeLevel7->content);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCardDAVDoc);
+
+ return UserPrincipalURI;
+
+}
+
+std::string CardDAV2::GetAddressBookHomeURI(){
+
+ xmlDocPtr xmlCardDAVDoc;
+ xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+ string AddressBookHomeURI = "";
+
+ xmlNodePtr nodeLevel1;
+ xmlNodePtr nodeLevel2;
+ xmlNodePtr nodeLevel3;
+ xmlNodePtr nodeLevel4;
+ xmlNodePtr nodeLevel5;
+ xmlNodePtr nodeLevel6;
+ xmlNodePtr nodeLevel7;
+
+ for (nodeLevel1 = xmlCardDAVDoc->children;
+ nodeLevel1 != NULL;
+ nodeLevel1 = nodeLevel1->next)
+ {
+
+ for (nodeLevel2 = nodeLevel1->children;
+ nodeLevel2 != NULL;
+ nodeLevel2 = nodeLevel2->next)
+ {
+
+
+ for (nodeLevel3 = nodeLevel2->children;
+ nodeLevel3 != NULL;
+ nodeLevel3 = nodeLevel3->next)
+ {
+
+ for (nodeLevel4 = nodeLevel3->children;
+ nodeLevel4 != NULL;
+ nodeLevel4 = nodeLevel4->next)
+ {
+
+ for (nodeLevel5 = nodeLevel4->children;
+ nodeLevel5 != NULL;
+ nodeLevel5 = nodeLevel5->next)
+ {
+
+ for (nodeLevel6 = nodeLevel5->children;
+ nodeLevel6 != NULL;
+ nodeLevel6 = nodeLevel6->next)
+ {
+
+ if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+ ){
+
+ // Found the <href> part so extract the principal URL address.
+
+ for (nodeLevel7 = nodeLevel6->children;
+ nodeLevel7 != NULL;
+ nodeLevel7 = nodeLevel7->next)
+ {
+
+ AddressBookHomeURI = ((const char*)nodeLevel7->content);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCardDAVDoc);
+
+ return AddressBookHomeURI;
+
+}
+
+std::string CardDAV2::GetDefaultAddressBookURI(){
+
+ xmlDocPtr xmlCardDAVDoc;
+ xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+ string DefaultAddressBookURI = "";
+
+ xmlNodePtr nodeLevel1;
+ xmlNodePtr nodeLevel2;
+ xmlNodePtr nodeLevel3;
+ xmlNodePtr nodeLevel4;
+ xmlNodePtr nodeLevel5;
+ xmlNodePtr nodeLevel6;
+ xmlNodePtr nodeLevel7;
+
+ for (nodeLevel1 = xmlCardDAVDoc->children;
+ nodeLevel1 != NULL;
+ nodeLevel1 = nodeLevel1->next)
+ {
+
+ for (nodeLevel2 = nodeLevel1->children;
+ nodeLevel2 != NULL;
+ nodeLevel2 = nodeLevel2->next)
+ {
+
+
+ for (nodeLevel3 = nodeLevel2->children;
+ nodeLevel3 != NULL;
+ nodeLevel3 = nodeLevel3->next)
+ {
+
+ for (nodeLevel4 = nodeLevel3->children;
+ nodeLevel4 != NULL;
+ nodeLevel4 = nodeLevel4->next)
+ {
+
+ for (nodeLevel5 = nodeLevel4->children;
+ nodeLevel5 != NULL;
+ nodeLevel5 = nodeLevel5->next)
+ {
+
+ for (nodeLevel6 = nodeLevel5->children;
+ nodeLevel6 != NULL;
+ nodeLevel6 = nodeLevel6->next)
+ {
+
+ if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+ !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+ ){
+
+ // Found the <href> part so extract the principal URL address.
+
+ for (nodeLevel7 = nodeLevel6->children;
+ nodeLevel7 != NULL;
+ nodeLevel7 = nodeLevel7->next)
+ {
+
+ DefaultAddressBookURI = ((const char*)nodeLevel7->content);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ xmlFreeDoc(xmlCardDAVDoc);
+
+ return DefaultAddressBookURI;
+
+}
+
+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){
+
+}
+
+COServerResponse CardDAV2::GetContact(std::string Location){
+
+}
+
+COContactList CardDAV2::GetContactList(std::string SyncToken){
+
+}
+
+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;
+
+ 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");
+
+ if (DoAuthentication == true){
+ curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+ } else {
+ curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");
+ }
+
+}
+
+void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
+
+ // Setup the default parameters.
+
+ string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
+ string UsernamePassword = ServerUser + ":" + ServerPass;
+
+ 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");
+
+ if (DoAuthentication == true){
+ curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
+ } else {
+ curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");
+ }
+
+ 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);
+ }
+
+}
+
+string CardDAV2::BuildURL(string URI){
+
+ string ServerAddressURL;
+
+ if (SSLStatus == true){
+ ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;
+ } else {
+ ServerAddressURL = "https://" + 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';
+ PageData = "";
+ PageHeader = "";
+
+}
+
+vector<string> CardDAV2::GetDAVHeader(){
+
+ // Go through each of the lines looking for the
+ // 'DAV:' section.
+
+
+ string HeaderName;
+ string HeaderValue;
+ bool DAVFound = false;
+ bool FastForward = false;
+ vector<string> DAVHeaderList;
+
+ for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
+
+ if (FastForward == true){
+
+ if (PageHeader[HeaderSeek] == '\n'){
+ FastForward = false;
+ }
+
+ continue;
+
+ }
+
+ try {
+ PageHeader.substr(HeaderSeek, 4) == "DAV:";
+ }
+
+ catch (const out_of_range &oor){
+ break;
+ }
+
+ if (PageHeader.substr(HeaderSeek, 4) == "DAV:"){
+
+ int CharacterSeek = 5;
+
+ while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
+
+ if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
+ break;
+ }
+
+ HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
+ CharacterSeek++;
+ }
+
+ break;
+
+ } else {
+
+ FastForward = true;
+ continue;
+
+ }
+
+ if (PageHeader[HeaderSeek] == '\n'){
+ HeaderName = "";
+ }
+
+ //HeaderName += PageHeader.substr(HeaderSeek, 1);
+
+ }
+
+ // Split the header data.
+
+ std::string DAVHeaderValue;
+
+ for (int HeaderSeek = 0; HeaderSeek < HeaderValue.size(); HeaderSeek++){
+
+ if (HeaderValue.substr(HeaderSeek, 1) == ","){
+ DAVHeaderList.push_back(DAVHeaderValue);
+ DAVHeaderValue = "";
+ HeaderSeek++;
+ continue;
+ }
+
+ DAVHeaderValue += HeaderValue[HeaderSeek];
+
+ }
+
+ if (DAVHeaderValue.size() > 0){
+
+ DAVHeaderList.push_back(DAVHeaderValue);
+
+ }
+
+ return DAVHeaderList;
+
+}
\ No newline at end of file