Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Implemented DeleteContact in the CardDAV2 class
[xestiaab/.git] / source / carddav2 / carddav2.cpp
1 // CardDAV2.cpp - CardDAV v2 class
2 //
3 // (c) 2012-2016 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
10 //
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/> 
19 #include "carddav2.h"
21 #include <iostream>
23 using namespace std;
25 size_t CardDAV2::WritebackFunc(char *ptr, size_t size, size_t nmemb, void *stream){
26         
27         return static_cast<CardDAV2*>(stream)->WritebackFuncImplementation(ptr, size, nmemb, stream);
28         
29 }
30         
31 size_t CardDAV2::WritebackFuncImplementation(char *ptr, size_t size, size_t nmemb, void *stream){
32         
33         // Writeback function for the CardDAV object.
34                 
35         string *data = static_cast<string*>(stream);
36         data->append(ptr);
37         
38         // Get the SSL engine pointer and trust if required on certain operating systems.
39         
40         if (ServerSSL){
41         
42 #if defined(__APPLE__)
43         
44                 const struct curl_tlssessioninfo *TLSInfo;
45                 CURLcode TLSCode;
46                 CURL *Connection = GetConnectionObject();
47                 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
48         
49                 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
50                         SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject);
51                 }
52         
53 #elif defined(__WIN32__)
55                 const struct curl_tlssessioninfo *TLSInfo;
56                 CURLcode TLSCode;
57                 CURL *Connection = GetConnectionObject();
58                 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
60                 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
62                         // Free the previous certificate data.
64                         CertFreeCertificateContext(CertificateData);
66                         PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
67                         SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
69                 }
71 #endif
73         }
74         
75         return size * nmemb;
77 }
79 CardDAV2::~CardDAV2(){
80         
81         curl_easy_cleanup(ConnectionSession);
82         ConnectionSession = nullptr;
83         
84         if (HeaderList != nullptr){
85                 curl_slist_free_all(HeaderList);
86                 HeaderList = nullptr;
87         }
88         
89 }
91 #if defined(__APPLE__)
93 #elif defined(__WIN32__)
95 #else
97 SSLCertCollectionString CardDAV2::BuildSSLCollection(){
99         // Build and return the SSL collection.
100         
101         SSLCertCollectionString SSLCertInfo;
103         // Grab the certificate data.
105         union {
106                 struct curl_slist *certdata;
107                 struct curl_certinfo *certinfo;
108         } certptr;
110         certptr.certdata = NULL;
111         
112         curl_easy_getinfo(ConnectionSession, CURLINFO_CERTINFO, &certptr.certinfo);
114         std::string CertPropName;
115         std::string CertPropValue;
117         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
119                 struct curl_slist *slist;
120                 SSLCertDataString SSLCertDataInc;
121                 
122                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
123                         
124                         // Using wxStringTokenizer from wxWidgets.
125                         
126                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");
127                         
128                         // Get first token as the property name.
129                         
130                         CertPropName = CertDataInc.GetNextToken().ToStdString();
131                         
132                         // Get remaining tokens as the property value.
133                         
134                         while(CertDataInc.HasMoreTokens()){
135                         
136                                 CertPropValue.append(CertDataInc.GetNextToken());
137                         
138                         }
139                         
140                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));
141                         CertPropName.clear();
142                         CertPropValue.clear();
143                         
144                 }
145         
146                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));
147         
148         }
149         
150         return SSLCertInfo;
154 void CardDAV2::BypassSSLVerification(bool EnableBypass){
155         EnableSSLBypass = EnableBypass;
156         SSLSelfSigned = EnableBypass;
159 #endif
161 void CardDAV2::SetupConnectionObject(){
162         ConnectionSession = curl_easy_init();
165 bool CardDAV2::IsTaskCompleted(){
166         return false;
169 COConnectResult CardDAV2::Connect(bool DoAuthentication){
170         
171         ServerSSL ? SetupDefaultParametersSSL(DoAuthentication) : SetupDefaultParametersNonSSL(DoAuthentication);
172         ResetResults();
173         
174         COConnectResult ConnectResult = COCONNECT_UNITTESTFAIL;
175         string ServerAddressURL = BuildURL("/principals/");
177         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
178         
179         if (TestMode == true){
180                 SessionResult = curl_easy_perform(ConnectionSession);
181         } else {
182                 SessionResult = curl_easy_perform(ConnectionSession);           
183         }
184         
185         switch(SessionResult){
186                 case CURLE_OK:
187                 case CURLE_HTTP_RETURNED_ERROR:
188                         SSLStatus = true;
189                         SSLVerified = COSSL_VERIFIED;
190                         ConnectResult = COCONNECT_OK;
191                         break;
192                 case CURLE_SSL_CACERT:
193                 case CURLE_SSL_CONNECT_ERROR:
194                         SSLStatus = true;
195                         ConnectResult = COCONNECT_OK;
196                         SSLVerified = COSSL_UNABLETOVERIFY;
197                         break;
198                 default:
199                         ConnectResult = COCONNECT_INVALID;
200                         break;
201         };
202         
203         // Check if an error occured before continuing.
204         
205         // Check if authentication was successful.
206         
207         long SessionResponseCode = 0;
208         
209         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
210         
211         if (DoAuthentication == true){
212                 
213                 // Get the HTTP status code (Should be 200 and not 403).
214                 // Return error otherwise.
215                 
216                 if (SessionResponseCode == 200){
217                         ConnectResult = COCONNECT_OK;
218                         AuthPassed = true;
219                         ValidResponse = true;
220                 } else if (SessionResponseCode == 401){
221                         ConnectResult = COCONNECT_AUTHFAIL;
222                         AuthPassed = false;
223                         ValidResponse = true;
224                 } else if (SessionResponseCode >= 200) {
225                         ConnectResult = COCONNECT_INVALID;
226                         AuthPassed = false;
227                         ValidResponse = true;
228                 } else {
229                         ConnectResult = COCONNECT_INVALID;
230                         AuthPassed = false;
231                         ValidResponse = false;                  
232                 }
233                 
234         } else {
235                 
236                 ValidResponse = true;
237                 
238         }
239         
240         // Check the header to see if CardDAV is supported.
241         
242         vector<string> DAVHeaderValues = GetDAVHeader();
243         
244         for (vector<string>::iterator DAVHeaderValuesIter = DAVHeaderValues.begin();
245                 DAVHeaderValuesIter != DAVHeaderValues.end(); DAVHeaderValuesIter++){
246                 
247                 if ((*DAVHeaderValuesIter) == "addressbook"){
248                         CanProcess = true;
249                         break;
250                 }
251                         
252         }
253         
254         return ConnectResult;
255         
258 COServerResponse CardDAV2::GetDefaultPrefix(string *ServerPrefix){
260         // Check if authentication was successful, otherwise don't do anything.
262         COServerResponse ServerResponse;
263         
264         if (AuthPassed == false){
265                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
266                 ServerResponse.EntityTag = "";
267                 ServerResponse.SessionCode = 0;
268                 ServerResponse.ResultCode = 0;
269                 ServerResponse.ResultMessage = "";
270                 return ServerResponse;
271         }
273         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
274         ResetResults();
275         
276         // Need to do three requests:
277         
278         // 1. Get the current user principal URI.
279         // 2. Get the address book home URI.
280         // 3. Get the default address book URI.
281         
282         // Setup the first query finding out where the principal URL is.
283         
284         const char* CurrentUserPrincipalXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
285                 "<D:propfind xmlns:D=\"DAV:\">\n"
286                 " <D:prop>"
287                 "  <D:current-user-principal/>\n"
288                 " </D:prop>"
289                 "</D:propfind>";
291         // Setup the second query finding out where the address book home URL is.
292         
293         const char* AddressBookHomeXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
294         "<D:propfind xmlns:D=\"DAV:\""
295         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
296         "  <D:prop>\n"
297         "    <C:addressbook-home-set/>\n"
298         "  </D:prop>\n"
299         "</D:propfind>";
300         
301         // Setup the third query finding out where the default address book URL is.
302         
303         const char* DefaultAddressBookXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
304         "<D:propfind xmlns:D=\"DAV:\""
305         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
306         "  <D:prop>\n"
307         "    <C:default-addressbook-URL/>\n"    
308         "  </D:prop>\n"
309         "</D:propfind>";
310         
311         string ServerAddressURL = BuildURL("/principals/");
312         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
313         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
314         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, CurrentUserPrincipalXMLQuery);
315         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(CurrentUserPrincipalXMLQuery));
316         
317         if (TestMode == true){
318                 SessionResult = curl_easy_perform(ConnectionSession);
319         } else {
320                 
321         }
322         
323         switch(SessionResult){
324                 case CURLE_OK:
325                         SSLStatus = true;
326                         SSLVerified = COSSL_VERIFIED;
327                         break;
328                 case CURLE_SSL_CACERT:
329                 case CURLE_SSL_CONNECT_ERROR:
330                         SSLStatus = true;
331                         SSLVerified = COSSL_UNABLETOVERIFY;
332                         break;
333                 default:
334                         break;
335         };
336         
337         long SessionResponseCode = 0;
338         
339         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
340         
341         if (SessionResponseCode == 200 || SessionResponseCode == 207){
342                 AuthPassed = true;
343                 ValidResponse = true;
344         } else if (SessionResponseCode == 403){
345                 AuthPassed = false;
346                 ValidResponse = true;
347         } else if (SessionResponseCode >= 400) {
348                 AuthPassed = false;
349                 ValidResponse = true;
350         } else {
351                 AuthPassed = false;
352                 ValidResponse = false;                  
353         }
354         
355         if (ValidResponse == false && AuthPassed == false){
356                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
357                 ServerResponse.EntityTag = "";
358                 ServerResponse.SessionCode = SessionResult;
359                 ServerResponse.ResultCode = SessionResponseCode;
360                 ServerResponse.ResultMessage = "";
361                 return ServerResponse;
362         }
363         
364         // Process the first response.
365         
366         string UserPrincipalURI = GetUserPrincipalURI();
367         
368         // Cleanup and reset for the second connection.
369         
370         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
371         ResetResults();
373         ServerAddressURL = BuildURL(UserPrincipalURI);
374         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
375         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
376         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, AddressBookHomeXMLQuery);
377         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(AddressBookHomeXMLQuery));
378         
379         if (TestMode == true){
380                 SessionResult = curl_easy_perform(ConnectionSession);
381         } else {
382                 
383         }
384         
385         switch(SessionResult){
386                 case CURLE_OK:
387                         SSLStatus = true;
388                         SSLVerified = COSSL_VERIFIED;
389                         break;
390                 case CURLE_SSL_CACERT:
391                 case CURLE_SSL_CONNECT_ERROR:
392                         SSLStatus = true;
393                         SSLVerified = COSSL_UNABLETOVERIFY;
394                         break;
395                 default:
396                         break;
397         };
398         
399         SessionResponseCode = 0;
400         
401         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
402         
403         if (SessionResponseCode == 200 || SessionResponseCode == 207){
404                 AuthPassed = true;
405                 ValidResponse = true;
406         } else if (SessionResponseCode == 403){
407                 AuthPassed = false;
408                 ValidResponse = true;
409         } else if (SessionResponseCode >= 400) {
410                 AuthPassed = false;
411                 ValidResponse = true;
412         } else {
413                 AuthPassed = false;
414                 ValidResponse = false;                  
415         }
416         
417         if (ValidResponse == false && AuthPassed == false){
418                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
419                 ServerResponse.EntityTag = "";
420                 ServerResponse.SessionCode = SessionResult;
421                 ServerResponse.ResultCode = SessionResponseCode;
422                 ServerResponse.ResultMessage = "";
423                 return ServerResponse;
424         }
425         
426         // Process the second response.
427         
428         string AddressBookHomeURI = GetAddressBookHomeURI();
429         
430         // Cleanup and reset for the second connection.
431         
432         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
433         ResetResults();
434         
435         ServerAddressURL = BuildURL(AddressBookHomeURI);
436         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
437         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
438         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, DefaultAddressBookXMLQuery);
439         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(DefaultAddressBookXMLQuery));
440         
441         if (TestMode == true){
442                 SessionResult = curl_easy_perform(ConnectionSession);
443         } else {
444                 
445         }
446         
447         switch(SessionResult){
448                 case CURLE_OK:
449                         SSLStatus = true;
450                         SSLVerified = COSSL_VERIFIED;
451                         break;
452                 case CURLE_SSL_CACERT:
453                 case CURLE_SSL_CONNECT_ERROR:
454                         SSLStatus = true;
455                         SSLVerified = COSSL_UNABLETOVERIFY;
456                         break;
457                 default:
458                         break;
459         };
460         
461         SessionResponseCode = 0;
462         
463         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
464         
465         if (SessionResponseCode == 200 || SessionResponseCode == 207){
466                 AuthPassed = true;
467                 ValidResponse = true;
468         } else if (SessionResponseCode == 403){
469                 AuthPassed = false;
470                 ValidResponse = true;
471         } else if (SessionResponseCode >= 200) {
472                 AuthPassed = false;
473                 ValidResponse = true;
474         } else {
475                 AuthPassed = false;
476                 ValidResponse = false;                  
477         }
478         
479         if (ValidResponse == false || AuthPassed == false){
480                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
481                 ServerResponse.EntityTag = "";
482                 ServerResponse.SessionCode = SessionResult;
483                 ServerResponse.ResultCode = SessionResponseCode;
484                 ServerResponse.ResultMessage = "";
485                 return ServerResponse;
486         }
487         
488         // Process the second response.
489         
490         (*ServerPrefix) = GetDefaultAddressBookURI();
491         
492         CanProcess = true;
493         
494         ServerResponse.RequestResult = COREQUEST_OK;
495         ServerResponse.EntityTag = "";
496         ServerResponse.SessionCode = SessionResult;
497         ServerResponse.ResultCode = SessionResponseCode;
498         ServerResponse.ResultMessage = SessionErrorBuffer;
499         return ServerResponse;
500         
503 std::string CardDAV2::GetUserPrincipalURI(){
504         
505         xmlDocPtr xmlCardDAVDoc;
506         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
507         string UserPrincipalURI = "";
508         
509         xmlNodePtr nodeLevel1;
510         xmlNodePtr nodeLevel2;
511         xmlNodePtr nodeLevel3;
512         xmlNodePtr nodeLevel4;
513         xmlNodePtr nodeLevel5;
514         xmlNodePtr nodeLevel6;
515         xmlNodePtr nodeLevel7;
516                 
517         for (nodeLevel1 = xmlCardDAVDoc->children;
518                 nodeLevel1 != NULL;
519                 nodeLevel1 = nodeLevel1->next)
520         {
522                 for (nodeLevel2 = nodeLevel1->children;
523                         nodeLevel2 != NULL;
524                         nodeLevel2 = nodeLevel2->next)
525                 {
528                         for (nodeLevel3 = nodeLevel2->children;
529                         nodeLevel3 != NULL;
530                         nodeLevel3 = nodeLevel3->next)
531                         {
532                         
533                                 for (nodeLevel4 = nodeLevel3->children;
534                                 nodeLevel4 != NULL;
535                                 nodeLevel4 = nodeLevel4->next)
536                                 {
537                         
538                                         for (nodeLevel5 = nodeLevel4->children;
539                                         nodeLevel5 != NULL;
540                                         nodeLevel5 = nodeLevel5->next)
541                                         {
542                         
543                                                 for (nodeLevel6 = nodeLevel5->children;
544                                                 nodeLevel6 != NULL;
545                                                 nodeLevel6 = nodeLevel6->next)
546                                                 {
547                         
548                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
549                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
550                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
551                                                         ){
552                         
553                                                                 // Found the <href> part so extract the principal URL address.
554                                                                 
555                                                                 for (nodeLevel7 = nodeLevel6->children;
556                                                                 nodeLevel7 != NULL;
557                                                                 nodeLevel7 = nodeLevel7->next)
558                                                                 {
559                                                                 
560                                                                         UserPrincipalURI = ((const char*)nodeLevel7->content);
562                                                                 }
563                         
564                                                         }
565                         
566                                                 }
567                         
568                                         }
569                         
570                                 }
571                         
572                         }
573                 
574                 }
575                 
576         }
577         
578         xmlFreeDoc(xmlCardDAVDoc);
579         
580         return UserPrincipalURI;
581         
584 std::string CardDAV2::GetAddressBookHomeURI(){
585         
586         xmlDocPtr xmlCardDAVDoc;
587         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
588         string AddressBookHomeURI = "";
589         
590         xmlNodePtr nodeLevel1;
591         xmlNodePtr nodeLevel2;
592         xmlNodePtr nodeLevel3;
593         xmlNodePtr nodeLevel4;
594         xmlNodePtr nodeLevel5;
595         xmlNodePtr nodeLevel6;
596         xmlNodePtr nodeLevel7;
597                 
598         for (nodeLevel1 = xmlCardDAVDoc->children;
599                 nodeLevel1 != NULL;
600                 nodeLevel1 = nodeLevel1->next)
601         {
603                 for (nodeLevel2 = nodeLevel1->children;
604                         nodeLevel2 != NULL;
605                         nodeLevel2 = nodeLevel2->next)
606                 {
609                         for (nodeLevel3 = nodeLevel2->children;
610                         nodeLevel3 != NULL;
611                         nodeLevel3 = nodeLevel3->next)
612                         {
613                         
614                                 for (nodeLevel4 = nodeLevel3->children;
615                                 nodeLevel4 != NULL;
616                                 nodeLevel4 = nodeLevel4->next)
617                                 {
618                         
619                                         for (nodeLevel5 = nodeLevel4->children;
620                                         nodeLevel5 != NULL;
621                                         nodeLevel5 = nodeLevel5->next)
622                                         {
623                         
624                                                 for (nodeLevel6 = nodeLevel5->children;
625                                                 nodeLevel6 != NULL;
626                                                 nodeLevel6 = nodeLevel6->next)
627                                                 {
628                         
629                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
630                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
631                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
632                                                         ){
633                         
634                                                                 // Found the <href> part so extract the principal URL address.
635                                                                 
636                                                                 for (nodeLevel7 = nodeLevel6->children;
637                                                                 nodeLevel7 != NULL;
638                                                                 nodeLevel7 = nodeLevel7->next)
639                                                                 {
640                                                                 
641                                                                         AddressBookHomeURI = ((const char*)nodeLevel7->content);
643                                                                 }
644                         
645                                                         }
646                         
647                                                 }
648                         
649                                         }
650                         
651                                 }
652                         
653                         }
654                 
655                 }
656                 
657         }
658         
659         xmlFreeDoc(xmlCardDAVDoc);
660         
661         return AddressBookHomeURI;
662         
665 std::string CardDAV2::GetDefaultAddressBookURI(){
666         
667         xmlDocPtr xmlCardDAVDoc;
668         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
669         string DefaultAddressBookURI = "";
670         
671         xmlNodePtr nodeLevel1;
672         xmlNodePtr nodeLevel2;
673         xmlNodePtr nodeLevel3;
674         xmlNodePtr nodeLevel4;
675         xmlNodePtr nodeLevel5;
676         xmlNodePtr nodeLevel6;
677         xmlNodePtr nodeLevel7;
678                 
679         for (nodeLevel1 = xmlCardDAVDoc->children;
680                 nodeLevel1 != NULL;
681                 nodeLevel1 = nodeLevel1->next)
682         {
684                 for (nodeLevel2 = nodeLevel1->children;
685                         nodeLevel2 != NULL;
686                         nodeLevel2 = nodeLevel2->next)
687                 {
690                         for (nodeLevel3 = nodeLevel2->children;
691                         nodeLevel3 != NULL;
692                         nodeLevel3 = nodeLevel3->next)
693                         {
694                         
695                                 for (nodeLevel4 = nodeLevel3->children;
696                                 nodeLevel4 != NULL;
697                                 nodeLevel4 = nodeLevel4->next)
698                                 {
699                         
700                                         for (nodeLevel5 = nodeLevel4->children;
701                                         nodeLevel5 != NULL;
702                                         nodeLevel5 = nodeLevel5->next)
703                                         {
704                         
705                                                 for (nodeLevel6 = nodeLevel5->children;
706                                                 nodeLevel6 != NULL;
707                                                 nodeLevel6 = nodeLevel6->next)
708                                                 {
709                         
710                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
711                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
712                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
713                                                         ){
714                         
715                                                                 // Found the <href> part so extract the principal URL address.
716                                                                 
717                                                                 for (nodeLevel7 = nodeLevel6->children;
718                                                                 nodeLevel7 != NULL;
719                                                                 nodeLevel7 = nodeLevel7->next)
720                                                                 {
721                                                                 
722                                                                         DefaultAddressBookURI = ((const char*)nodeLevel7->content);
724                                                                 }
725                         
726                                                         }
727                         
728                                                 }
729                         
730                                         }
731                         
732                                 }
733                         
734                         }
735                 
736                 }
737                 
738         }
739         
740         xmlFreeDoc(xmlCardDAVDoc);
741         
742         return DefaultAddressBookURI;
743         
746 COServerResponse CardDAV2::AddContact(std::string Location, std::string Data){
747         
748         // Check if authentication was successful, otherwise don't do anything.
750         COServerResponse ServerResponse;
751         
752         if (AuthPassed == false){
753                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
754                 ServerResponse.EntityTag = "";
755                 ServerResponse.SessionCode = 0;
756                 ServerResponse.ResultCode = 0;
757                 ServerResponse.ResultMessage = "";
758                 return ServerResponse;
759         }
761         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
762         ResetResults();
763         
764         string ServerAddressURL = BuildURL(ServerPrefix + Location);
765         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
766         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PUT");
767         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, Data.c_str());
768         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(Data.c_str()));
769         
770         HeaderList = curl_slist_append(HeaderList, "Content-Type: text/vcard; charset=utf-8");
772         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
773         
774         if (TestMode == true){
775                 SessionResult = curl_easy_perform(ConnectionSession);
776         } else {
777                 SessionResult = curl_easy_perform(ConnectionSession);
778         }
779         
780         switch(SessionResult){
781                 case CURLE_OK:
782                         SSLStatus = true;
783                         SSLVerified = COSSL_VERIFIED;
784                         break;
785                 case CURLE_SSL_CACERT:
786                 case CURLE_SSL_CONNECT_ERROR:
787                         SSLStatus = true;
788                         SSLVerified = COSSL_UNABLETOVERIFY;
789                         break;
790                 default:
791                         break;
792         };
793         
794         long SessionResponseCode = 0;
795         
796         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
797         
798         if (SessionResponseCode == 200 || SessionResponseCode == 201 || SessionResponseCode == 204){
799                 AuthPassed = true;
800                 ValidResponse = true;
801         } else if (SessionResponseCode == 403){
802                 AuthPassed = false;
803                 ValidResponse = true;
804         } else if (SessionResponseCode >= 400){
805                 AuthPassed = false;
806                 ValidResponse = true;
807         } else {
808                 AuthPassed = false;
809                 ValidResponse = false;                  
810         }
811         
812         if (ValidResponse == false || AuthPassed == false){
813                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
814                 ServerResponse.EntityTag = "";
815                 ServerResponse.SessionCode = SessionResult;
816                 ServerResponse.ResultCode = SessionResponseCode;
817                 ServerResponse.ResultMessage = "";
818                 return ServerResponse;
819         }
820         
821         CanProcess = true;
822         
823         ServerResponse.RequestResult = COREQUEST_OK;
824         ServerResponse.EntityTag = "";
825         ServerResponse.SessionCode = SessionResult;
826         ServerResponse.ResultCode = SessionResponseCode;
827         ServerResponse.ResultMessage = SessionErrorBuffer;
828         return ServerResponse;
829         
832 COServerResponse CardDAV2::EditContact(std::string Location, std::string Data){
834         // Check if authentication was successful, otherwise don't do anything.
836         COServerResponse ServerResponse;
837         
838         if (AuthPassed == false){
839                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
840                 ServerResponse.EntityTag = "";
841                 ServerResponse.SessionCode = 0;
842                 ServerResponse.ResultCode = 0;
843                 ServerResponse.ResultMessage = "";
844                 return ServerResponse;
845         }
847         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
848         ResetResults();
849         
850         string ServerAddressURL = BuildURL(ServerPrefix + Location);
851         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
852         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PUT");
853         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, Data.c_str());
854         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(Data.c_str()));
855         
856         HeaderList = curl_slist_append(HeaderList, "Content-Type: text/vcard; charset=utf-8");
858         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
859         
860         if (TestMode == true){
861                 SessionResult = curl_easy_perform(ConnectionSession);
862         } else {
863                 SessionResult = curl_easy_perform(ConnectionSession);
864         }
865         
866         switch(SessionResult){
867                 case CURLE_OK:
868                         SSLStatus = true;
869                         SSLVerified = COSSL_VERIFIED;
870                         break;
871                 case CURLE_SSL_CACERT:
872                 case CURLE_SSL_CONNECT_ERROR:
873                         SSLStatus = true;
874                         SSLVerified = COSSL_UNABLETOVERIFY;
875                         break;
876                 default:
877                         break;
878         };
879         
880         long SessionResponseCode = 0;
881         
882         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
883         
884         if (SessionResponseCode == 200 || SessionResponseCode == 201 || SessionResponseCode == 204){
885                 AuthPassed = true;
886                 ValidResponse = true;
887         } else if (SessionResponseCode == 403){
888                 AuthPassed = false;
889                 ValidResponse = true;
890         } else if (SessionResponseCode >= 400){
891                 AuthPassed = false;
892                 ValidResponse = true;
893         } else {
894                 AuthPassed = false;
895                 ValidResponse = false;                  
896         }
897         
898         if (ValidResponse == false || AuthPassed == false){
899                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
900                 ServerResponse.EntityTag = "";
901                 ServerResponse.SessionCode = SessionResult;
902                 ServerResponse.ResultCode = SessionResponseCode;
903                 ServerResponse.ResultMessage = "";
904                 return ServerResponse;
905         }
906         
907         CanProcess = true;
908         
909         ServerResponse.RequestResult = COREQUEST_OK;
910         ServerResponse.EntityTag = "";
911         ServerResponse.SessionCode = SessionResult;
912         ServerResponse.ResultCode = SessionResponseCode;
913         ServerResponse.ResultMessage = SessionErrorBuffer;
914         return ServerResponse;
915         
918 COServerResponse CardDAV2::DeleteContact(std::string Location){
919         
920         // Check if authentication was successful, otherwise don't do anything.
922         COServerResponse ServerResponse;
923         
924         if (AuthPassed == false){
925                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
926                 ServerResponse.EntityTag = "";
927                 ServerResponse.SessionCode = 0;
928                 ServerResponse.ResultCode = 0;
929                 ServerResponse.ResultMessage = "";
930                 return ServerResponse;
931         }
933         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
934         ResetResults();
935         
936         string ServerAddressURL = BuildURL(ServerPrefix + Location);
937         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
938         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "DELETE");
939         
940         if (TestMode == true){
941                 SessionResult = curl_easy_perform(ConnectionSession);
942         } else {
943                 SessionResult = curl_easy_perform(ConnectionSession);
944         }
945         
946         switch(SessionResult){
947                 case CURLE_OK:
948                         SSLStatus = true;
949                         SSLVerified = COSSL_VERIFIED;
950                         break;
951                 case CURLE_SSL_CACERT:
952                 case CURLE_SSL_CONNECT_ERROR:
953                         SSLStatus = true;
954                         SSLVerified = COSSL_UNABLETOVERIFY;
955                         break;
956                 default:
957                         break;
958         };
959         
960         long SessionResponseCode = 0;
961         
962         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
963         
964         if (SessionResponseCode == 200 || SessionResponseCode == 202 || SessionResponseCode == 204){
965                 AuthPassed = true;
966                 ValidResponse = true;
967         } else if (SessionResponseCode == 403){
968                 AuthPassed = false;
969                 ValidResponse = true;
970         } else if (SessionResponseCode >= 400){
971                 AuthPassed = false;
972                 ValidResponse = true;
973         } else {
974                 AuthPassed = false;
975                 ValidResponse = false;                  
976         }
977         
978         if (ValidResponse == false || AuthPassed == false){
979                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
980                 ServerResponse.EntityTag = "";
981                 ServerResponse.SessionCode = SessionResult;
982                 ServerResponse.ResultCode = SessionResponseCode;
983                 ServerResponse.ResultMessage = "";
984                 return ServerResponse;
985         }
986         
987         CanProcess = true;
988         
989         ServerResponse.RequestResult = COREQUEST_OK;
990         ServerResponse.EntityTag = "";
991         ServerResponse.SessionCode = SessionResult;
992         ServerResponse.ResultCode = SessionResponseCode;
993         ServerResponse.ResultMessage = SessionErrorBuffer;
994         return ServerResponse;
995         
998 COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){
999         
1000         // Check if authentication was successful, otherwise don't do anything.
1002         COServerResponse ServerResponse;
1003         
1004         if (AuthPassed == false){
1005                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
1006                 ServerResponse.EntityTag = "";
1007                 ServerResponse.SessionCode = 0;
1008                 ServerResponse.ResultCode = 0;
1009                 ServerResponse.ResultMessage = "";
1010                 return ServerResponse;
1011         }
1013         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
1014         ResetResults();
1015         
1016         static const char* GetETagQuery =
1017         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1018         "<C:addressbook-query xmlns:D=\"DAV:\""
1019         "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
1020         "<D:prop><D:getetag/>"
1021         "</D:prop>"
1022         "<C:filter/>"
1023         "</C:addressbook-query>";
1024         
1025         string ServerAddressURL = BuildURL(ServerPrefix + Location);
1026         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
1027         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT");
1028         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, GetETagQuery);
1029         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(GetETagQuery));
1030         
1031         if (TestMode == true){
1032                 SessionResult = curl_easy_perform(ConnectionSession);
1033         } else {
1034                 SessionResult = curl_easy_perform(ConnectionSession);
1035         }
1036         
1037         switch(SessionResult){
1038                 case CURLE_OK:
1039                         SSLStatus = true;
1040                         SSLVerified = COSSL_VERIFIED;
1041                         break;
1042                 case CURLE_SSL_CACERT:
1043                 case CURLE_SSL_CONNECT_ERROR:
1044                         SSLStatus = true;
1045                         SSLVerified = COSSL_UNABLETOVERIFY;
1046                         break;
1047                 default:
1048                         break;
1049         };
1050         
1051         long SessionResponseCode = 0;
1052         
1053         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
1054         
1055         if (SessionResponseCode == 207){
1056                 AuthPassed = true;
1057                 ValidResponse = true;
1058         } else if (SessionResponseCode == 403){
1059                 AuthPassed = false;
1060                 ValidResponse = true;
1061         } else if (SessionResponseCode >= 400){
1062                 AuthPassed = false;
1063                 ValidResponse = true;
1064         } else {
1065                 AuthPassed = false;
1066                 ValidResponse = false;                  
1067         }
1068         
1069         if (ValidResponse == false || AuthPassed == false){
1070                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
1071                 ServerResponse.EntityTag = "";
1072                 ServerResponse.SessionCode = SessionResult;
1073                 ServerResponse.ResultCode = SessionResponseCode;
1074                 ServerResponse.ResultMessage = "";
1075                 return ServerResponse;
1076         }
1077         
1078         CanProcess = true;
1079         
1080         ServerResponse.RequestResult = COREQUEST_OK;
1081         ServerResponse.EntityTag = GetETagValue();
1082         ServerResponse.SessionCode = SessionResult;
1083         ServerResponse.ResultCode = SessionResponseCode;
1084         ServerResponse.ResultMessage = SessionErrorBuffer;
1085         
1086         return ServerResponse;
1087         
1090 COServerResponse CardDAV2::GetContact(std::string Location, std::string *ContactData){
1091         
1092         // Check if authentication was successful, otherwise don't do anything.
1094         COServerResponse ServerResponse;
1095         
1096         if (AuthPassed == false){
1097                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
1098                 ServerResponse.EntityTag = "";
1099                 ServerResponse.SessionCode = 0;
1100                 ServerResponse.ResultCode = 0;
1101                 ServerResponse.ResultMessage = "";
1102                 return ServerResponse;
1103         }
1105         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
1106         ResetResults();
1107         
1108         string ServerAddressURL = BuildURL(ServerPrefix + Location);
1109         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
1110         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1111         
1112         if (TestMode == true){
1113                 SessionResult = curl_easy_perform(ConnectionSession);
1114         } else {
1115                 SessionResult = curl_easy_perform(ConnectionSession);
1116         }
1117         
1118         switch(SessionResult){
1119                 case CURLE_OK:
1120                         SSLStatus = true;
1121                         SSLVerified = COSSL_VERIFIED;
1122                         break;
1123                 case CURLE_SSL_CACERT:
1124                 case CURLE_SSL_CONNECT_ERROR:
1125                         SSLStatus = true;
1126                         SSLVerified = COSSL_UNABLETOVERIFY;
1127                         break;
1128                 default:
1129                         break;
1130         };
1131         
1132         long SessionResponseCode = 0;
1133         
1134         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
1135         
1136         if (SessionResponseCode == 200){
1137                 AuthPassed = true;
1138                 ValidResponse = true;
1139         } else if (SessionResponseCode == 403){
1140                 AuthPassed = false;
1141                 ValidResponse = true;
1142         } else if (SessionResponseCode >= 400){
1143                 AuthPassed = false;
1144                 ValidResponse = true;
1145         } else {
1146                 AuthPassed = false;
1147                 ValidResponse = false;                  
1148         }
1149         
1150         if (ValidResponse == false && AuthPassed == false){
1151                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
1152                 ServerResponse.EntityTag = "";
1153                 ServerResponse.SessionCode = SessionResult;
1154                 ServerResponse.ResultCode = SessionResponseCode;
1155                 ServerResponse.ResultMessage = "";
1156                 return ServerResponse;
1157         }
1158         
1159         CanProcess = true;
1160         
1161         ServerResponse.RequestResult = COREQUEST_OK;
1162         ServerResponse.EntityTag = "";
1163         ServerResponse.SessionCode = SessionResult;
1164         ServerResponse.ResultCode = SessionResponseCode;
1165         ServerResponse.ResultMessage = SessionErrorBuffer;
1166         
1167         (*ContactData) = PageData;
1168         
1169         return ServerResponse;
1170         
1173 COContactList CardDAV2::GetContactList(std::string SyncToken){
1174         
1176         
1177 bool CardDAV2::CanDoProcessing(){
1178         return CanProcess;
1181 bool CardDAV2::CanDoSSL(){
1182         return SSLStatus;
1185 COSSLVerified CardDAV2::SSLVerify(){
1186         return SSLVerified;
1189 bool CardDAV2::AbleToLogin(){
1190         return AuthPassed;
1193 bool CardDAV2::HasValidResponse(){
1194         return ValidResponse;
1197 bool CardDAV2::IsSelfSigned(){
1198         return SSLSelfSigned;
1201 void CardDAV2::SetupDefaultParametersNonSSL(bool DoAuthentication){
1202         
1203         std::string ServerAddress = "";
1205         string ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + "/";
1206         string UsernamePassword = ServerUser + ":" + ServerPass;
1207         
1208         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddress.c_str());
1209         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
1210         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1211         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
1212         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
1213         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
1214         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
1215         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
1216         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
1217         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
1218         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1219         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
1220         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
1221         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
1222         
1223         if (DoAuthentication == true){
1224                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
1225         } else {
1226                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
1227         }
1228         
1231 void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
1232         
1233         // Setup the default parameters.
1234         
1235         string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
1236         string UsernamePassword = ServerUser + ":" + ServerPass;
1237         
1238         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
1239         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
1240         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1241         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
1242         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
1243         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
1244         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
1245         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
1246         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
1247         curl_easy_setopt(ConnectionSession, CURLOPT_ERRORBUFFER, SessionErrorBuffer);
1248         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
1249         curl_easy_setopt(ConnectionSession, CURLOPT_CERTINFO, 1);
1250         curl_easy_setopt(ConnectionSession, CURLOPT_VERBOSE, 1);
1251         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1252         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
1253         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
1254         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
1255         
1256         if (DoAuthentication == true){
1257                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
1258         } else {
1259                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
1260         }
1261         
1262         if (EnableSSLBypass == true){
1263                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 0);
1264                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 0);
1265         } else {
1266                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 2);
1267                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 1);         
1268         }
1269         
1270         if (TestMode == false && ServerAccount.size() > 0){
1271                 
1272                 // Check if the server certificate file exists.
1273                 
1274                 string CertificateFilename = GetAccountDir(ServerAccount, true);
1275                 
1276                 if (wxFile::Exists(CertificateFilename)){
1277                         
1278                         curl_easy_setopt(ConnectionSession, CURLOPT_CAINFO, CertificateFilename.c_str());
1279                         
1280                 }
1281                 
1282         }
1283         
1286 string CardDAV2::BuildURL(string URI){
1287         
1288         string ServerAddressURL;
1289         
1290         if (SSLStatus == true){
1291                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;      
1292         } else {
1293                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;
1294         }
1295         
1296         return ServerAddressURL;
1297         
1300 string CardDAV2::GetErrorMessage(){
1301         
1302         ErrorMessage = SessionErrorBuffer;      
1303         return ErrorMessage;
1304         
1307 void CardDAV2::ResetResults(){
1308         
1309         SSLStatus = false;
1310         COSSLVerified SSLVerified = COSSL_NORESULT;
1311         ValidResponse = false;
1312         AuthPassed = false;
1313         CanProcess = false;
1314         SSLSelfSigned = false;
1315         TaskCompleted = false;
1316         ErrorMessage = "";
1317         SessionErrorBuffer[0] = '\0';
1318         PageData = "";
1319         PageHeader = "";
1320         if (HeaderList != nullptr){
1321                 curl_slist_free_all(HeaderList);
1322                 HeaderList = nullptr;
1323         }
1324         
1327 string CardDAV2::GetETagValue(){
1328         
1329         xmlDocPtr xmlCardDAVDoc;
1331         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
1333         xmlNodePtr nodeLevel1;
1334         xmlNodePtr nodeLevel2;
1335         xmlNodePtr nodeLevel3;
1336         xmlNodePtr nodeLevel4;
1337         xmlNodePtr nodeLevel5;
1338         xmlNodePtr nodeLevel6;
1340         //std::map<wxString,wxString> xmlDataMap;
1342         std::string DataFilename;
1343         std::string ETagData;
1345         std::string xmlStringSafe;
1346         std::string ETagValue;
1348         // Tranverse through the catacombs of the response to get our ETag for the file.
1350         for (nodeLevel1 = xmlCardDAVDoc->children;
1351                 nodeLevel1 != NULL;
1352                 nodeLevel1 = nodeLevel1->next)
1353         {
1355                 bool HREFFound = FALSE;
1356                 bool ETagFound = FALSE;
1358                 for (nodeLevel2 = nodeLevel1->children;
1359                         nodeLevel2 != NULL;
1360                         nodeLevel2 = nodeLevel2->next)
1361                 {
1363                         for (nodeLevel3 = nodeLevel2->children;
1364                         nodeLevel3 != NULL;
1365                         nodeLevel3 = nodeLevel3->next)
1366                         {
1368                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
1369                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
1370                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
1371                                 ){
1373                                         // Get the filename.
1374                                         
1375                                         for (nodeLevel4 = nodeLevel3->children;
1376                                         nodeLevel4 != NULL;
1377                                         nodeLevel4 = nodeLevel4->next)
1378                                         {
1379                                         
1380                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
1381                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
1382                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
1383                                                 ){
1385                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
1386                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
1387                                                 
1388                                                         while (wSTDFilename.HasMoreTokens()){
1389                                                         
1390                                                                 DataFilename = wSTDFilename.GetNextToken().ToStdString();
1391                                                         
1392                                                         }
1393                                                         
1394                                                         HREFFound = TRUE;
1395                                                 
1396                                                 }
1397                                                 
1398         
1399                                         
1400                                         }
1402                                 } else {
1404                                         for (nodeLevel4 = nodeLevel3->children;
1405                                         nodeLevel4 != NULL;
1406                                         nodeLevel4 = nodeLevel4->next)
1407                                         {
1408                                                         
1409                                                         for (nodeLevel5 = nodeLevel4->children;
1410                                                         nodeLevel5 != NULL;
1411                                                         nodeLevel5 = nodeLevel5->next)
1412                                                         {
1414                                                                 if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
1415                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
1416                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
1417                                                                 ){
1419                                                                         for (nodeLevel6 = nodeLevel5->children;
1420                                                                         nodeLevel6 != NULL;
1421                                                                         nodeLevel6 = nodeLevel6->next)
1422                                                                         {
1423                                                         
1424                                                                                 // Strip the quotes from the ETag.
1425                                                         
1426                                                                                 ETagData = (const char*)nodeLevel6->content;
1427                                                                                 if (ETagData[0] == '"' && ETagData[(ETagData.size() - 1)] == '"'){
1428                                                         
1429                                                                                         ETagData.erase(0, 1);
1430                                                                                         ETagData.erase((ETagData.size() - 1));
1431                                                         
1432                                                                                 }
1433                                                                         
1434                                                                                 ETagFound = TRUE;
1436                                                                         }
1437                                                                         
1438                                                                 }
1440                                                         }       
1442                                         }
1444                                 }
1446                         }
1448                 }
1449                 
1450                 if (HREFFound == TRUE && ETagFound == TRUE){
1451                                 
1452                         // Add to the map data.
1453                                 
1454                         ETagValue = ETagData;
1455                         
1456                         HREFFound = FALSE;
1457                         ETagFound = FALSE;
1458                         break;
1459                                 
1460                 }
1463         }
1465         xmlFreeDoc(xmlCardDAVDoc);
1466         
1467         return ETagValue;
1468         
1471 string CardDAV2::GetETagHeader(){
1472         
1473         // Go through each of the lines looking for the
1474         // 'DAV:' section.
1475         
1476         string HeaderName;
1477         string HeaderValue;
1478         bool FastForward = false;
1479         
1480         for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
1481                 
1482                 if (FastForward == true){
1483                         
1484                         if (PageHeader[HeaderSeek] == '\n'){
1485                                 FastForward = false;
1486                         }
1487                         
1488                         continue;
1489                         
1490                 }
1491                 
1492                 try {
1493                         PageHeader.substr(HeaderSeek, 5) == "ETag:";
1494                 }
1495                 
1496                 catch (const out_of_range &oor){
1497                         break;
1498                 }
1499                 
1500                 if (PageHeader.substr(HeaderSeek, 5) == "ETag:"){
1501                         
1502                         int CharacterSeek = 5;
1503                         
1504                         while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
1505                                 
1506                                 if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
1507                                         break;
1508                                 }
1509                                 
1510                                 HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
1511                                 CharacterSeek++;
1512                         }
1513                         
1514                         break;
1515                         
1516                 } else {
1517                         
1518                         FastForward = true;
1519                         continue;
1520                         
1521                 }
1522                 
1523                 if (PageHeader[HeaderSeek] == '\n'){
1524                         HeaderName = "";
1525                 }
1526                 
1527                 //HeaderName += PageHeader.substr(HeaderSeek, 1);
1528                 
1529         }
1530         
1531         // Check for quotation marks at the start and end and strip
1532         // them out.
1533         
1534         if (HeaderValue.size() >= 2){
1535                 
1536                 if (HeaderValue[0] == '"'){
1537                         HeaderValue.erase((HeaderValue.size() - 1));
1538                         HeaderValue.erase(0);
1539                 }
1540                 
1541         }
1542         
1543         return HeaderValue;
1544         
1547 vector<string> CardDAV2::GetDAVHeader(){
1548         
1549         // Go through each of the lines looking for the
1550         // 'DAV:' section.
1551         
1552         string HeaderName;
1553         string HeaderValue;
1554         bool FastForward = false;
1555         vector<string> DAVHeaderList;
1556         
1557         for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
1558                 
1559                 if (FastForward == true){
1560                         
1561                         if (PageHeader[HeaderSeek] == '\n'){
1562                                 FastForward = false;
1563                         }
1564                         
1565                         continue;
1566                         
1567                 }
1568                 
1569                 try {
1570                         PageHeader.substr(HeaderSeek, 4) == "DAV:";
1571                 }
1572                 
1573                 catch (const out_of_range &oor){
1574                         break;
1575                 }
1576                 
1577                 if (PageHeader.substr(HeaderSeek, 4) == "DAV:"){
1578                         
1579                         int CharacterSeek = 5;
1580                         
1581                         while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
1582                                 
1583                                 if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
1584                                         break;
1585                                 }
1586                                 
1587                                 HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
1588                                 CharacterSeek++;
1589                         }
1590                         
1591                         break;
1592                         
1593                 } else {
1594                         
1595                         FastForward = true;
1596                         continue;
1597                         
1598                 }
1599                 
1600                 if (PageHeader[HeaderSeek] == '\n'){
1601                         HeaderName = "";
1602                 }
1603                 
1604                 //HeaderName += PageHeader.substr(HeaderSeek, 1);
1605                 
1606         }
1607         
1608         // Split the header data.
1609         
1610         std::string DAVHeaderValue;
1611         
1612         for (int HeaderSeek = 0; HeaderSeek < HeaderValue.size(); HeaderSeek++){
1613                 
1614                 if (HeaderValue.substr(HeaderSeek, 1) == ","){
1615                         DAVHeaderList.push_back(DAVHeaderValue);
1616                         DAVHeaderValue = "";
1617                         HeaderSeek++;
1618                         continue;
1619                 }
1620                 
1621                 DAVHeaderValue += HeaderValue[HeaderSeek];
1622                 
1623         }
1624         
1625         if (DAVHeaderValue.size() > 0){
1626                 
1627                 DAVHeaderList.push_back(DAVHeaderValue);
1628                 
1629         }
1630         
1631         return DAVHeaderList;
1632         
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