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