Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Initial version of 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         curl_easy_cleanup(ConnectionSession);
81         ConnectionSession = nullptr;
82 }
84 #if defined(__APPLE__)
86 #elif defined(__WIN32__)
88 #else
90 SSLCertCollectionString CardDAV2::BuildSSLCollection(){
92         // Build and return the SSL collection.
93         
94         SSLCertCollectionString SSLCertInfo;
96         // Grab the certificate data.
98         union {
99                 struct curl_slist *certdata;
100                 struct curl_certinfo *certinfo;
101         } certptr;
103         certptr.certdata = NULL;
104         
105         curl_easy_getinfo(ConnectionSession, CURLINFO_CERTINFO, &certptr.certinfo);
107         std::string CertPropName;
108         std::string CertPropValue;
110         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
112                 struct curl_slist *slist;
113                 SSLCertDataString SSLCertDataInc;
114                 
115                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
116                         
117                         // Using wxStringTokenizer from wxWidgets.
118                         
119                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");
120                         
121                         // Get first token as the property name.
122                         
123                         CertPropName = CertDataInc.GetNextToken().ToStdString();
124                         
125                         // Get remaining tokens as the property value.
126                         
127                         while(CertDataInc.HasMoreTokens()){
128                         
129                                 CertPropValue.append(CertDataInc.GetNextToken());
130                         
131                         }
132                         
133                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));
134                         CertPropName.clear();
135                         CertPropValue.clear();
136                         
137                 }
138         
139                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));
140         
141         }
142         
143         return SSLCertInfo;
147 void CardDAV2::BypassSSLVerification(bool EnableBypass){
148         EnableSSLBypass = EnableBypass;
149         SSLSelfSigned = EnableBypass;
152 #endif
154 void CardDAV2::SetupConnectionObject(){
155         ConnectionSession = curl_easy_init();
158 bool CardDAV2::IsTaskCompleted(){
159         return false;
162 COConnectResult CardDAV2::Connect(bool DoAuthentication){
163         
164         ServerSSL ? SetupDefaultParametersSSL(DoAuthentication) : SetupDefaultParametersNonSSL(DoAuthentication);
165         ResetResults();
166         
167         COConnectResult ConnectResult = COCONNECT_UNITTESTFAIL;
168         string ServerAddressURL = BuildURL("/principals/");
170         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
171         
172         if (TestMode == true){
173                 SessionResult = curl_easy_perform(ConnectionSession);
174         } else {
175                 
176         }
177         
178         switch(SessionResult){
179                 case CURLE_OK:
180                         SSLStatus = true;
181                         SSLVerified = COSSL_VERIFIED;
182                         ConnectResult = COCONNECT_OK;
183                         break;
184                 case CURLE_SSL_CACERT:
185                 case CURLE_SSL_CONNECT_ERROR:
186                         SSLStatus = true;
187                         ConnectResult = COCONNECT_OK;
188                         SSLVerified = COSSL_UNABLETOVERIFY;
189                         break;
190                 default:
191                         ConnectResult = COCONNECT_INVALID;
192                         break;
193         };
194         
195         // Check if an error occured before continuing.
196         
197         // Check if authentication was successful.
198         
199         long SessionResponseCode = 0;
200         
201         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
202         
203         if (DoAuthentication == true){
204                 
205                 // Get the HTTP status code (Should be 200 and not 403).
206                 // Return error otherwise.
207                 
208                 if (SessionResponseCode == 200){
209                         ConnectResult = COCONNECT_OK;
210                         AuthPassed = true;
211                         ValidResponse = true;
212                 } else if (SessionResponseCode == 403){
213                         ConnectResult = COCONNECT_AUTHFAIL;
214                         AuthPassed = false;
215                         ValidResponse = true;
216                 } else if (SessionResponseCode >= 200) {
217                         ConnectResult = COCONNECT_INVALID;
218                         AuthPassed = false;
219                         ValidResponse = true;
220                 } else {
221                         ConnectResult = COCONNECT_INVALID;
222                         AuthPassed = false;
223                         ValidResponse = false;                  
224                 }
225                 
226         } else {
227                 
228                 ValidResponse = true;
229                 
230         }
231         
232         // Check the header to see if CardDAV is supported.
233         
234         vector<string> DAVHeaderValues = GetDAVHeader();
235         
236         for (vector<string>::iterator DAVHeaderValuesIter = DAVHeaderValues.begin();
237                 DAVHeaderValuesIter != DAVHeaderValues.end(); DAVHeaderValuesIter++){
238                 
239                 if ((*DAVHeaderValuesIter) == "addressbook"){
240                         CanProcess = true;
241                         break;
242                 }
243                         
244         }
245         
246         return ConnectResult;
247         
250 COServerResponse CardDAV2::GetDefaultPrefix(string *ServerPrefix){
252         // Check if authentication was successful, otherwise don't do anything.
254         COServerResponse ServerResponse;
255         
256         if (AuthPassed == false){
257                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
258                 ServerResponse.EntityTag = "";
259                 ServerResponse.SessionCode = 0;
260                 ServerResponse.ResultCode = 0;
261                 ServerResponse.ResultMessage = "";
262                 return ServerResponse;
263         }
265         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
266         ResetResults();
267         
268         // Need to do three requests:
269         
270         // 1. Get the current user principal URI.
271         // 2. Get the address book home URI.
272         // 3. Get the default address book URI.
273         
274         // Setup the first query finding out where the principal URL is.
275         
276         const char* CurrentUserPrincipalXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
277                 "<D:propfind xmlns:D=\"DAV:\">\n"
278                 " <D:prop>"
279                 "  <D:current-user-principal/>\n"
280                 " </D:prop>"
281                 "</D:propfind>";
283         // Setup the second query finding out where the address book home URL is.
284         
285         const char* AddressBookHomeXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
286         "<D:propfind xmlns:D=\"DAV:\""
287         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
288         "  <D:prop>\n"
289         "    <C:addressbook-home-set/>\n"
290         "  </D:prop>\n"
291         "</D:propfind>";
292         
293         // Setup the third query finding out where the default address book URL is.
294         
295         const char* DefaultAddressBookXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
296         "<D:propfind xmlns:D=\"DAV:\""
297         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
298         "  <D:prop>\n"
299         "    <C:default-addressbook-URL/>\n"    
300         "  </D:prop>\n"
301         "</D:propfind>";
302         
303         string ServerAddressURL = BuildURL("/principals/");
304         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
305         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
306         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, CurrentUserPrincipalXMLQuery);
307         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(CurrentUserPrincipalXMLQuery));
308         
309         if (TestMode == true){
310                 SessionResult = curl_easy_perform(ConnectionSession);
311         } else {
312                 
313         }
314         
315         switch(SessionResult){
316                 case CURLE_OK:
317                         SSLStatus = true;
318                         SSLVerified = COSSL_VERIFIED;
319                         break;
320                 case CURLE_SSL_CACERT:
321                 case CURLE_SSL_CONNECT_ERROR:
322                         SSLStatus = true;
323                         SSLVerified = COSSL_UNABLETOVERIFY;
324                         break;
325                 default:
326                         break;
327         };
328         
329         long SessionResponseCode = 0;
330         
331         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
332         
333         if (SessionResponseCode == 200 || SessionResponseCode == 207){
334                 AuthPassed = true;
335                 ValidResponse = true;
336         } else if (SessionResponseCode == 403){
337                 AuthPassed = false;
338                 ValidResponse = true;
339         } else if (SessionResponseCode >= 200) {
340                 AuthPassed = false;
341                 ValidResponse = true;
342         } else {
343                 AuthPassed = false;
344                 ValidResponse = false;                  
345         }
346         
347         if (ValidResponse == false && AuthPassed == false){
348                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
349                 ServerResponse.EntityTag = "";
350                 ServerResponse.SessionCode = SessionResult;
351                 ServerResponse.ResultCode = SessionResponseCode;
352                 ServerResponse.ResultMessage = "";
353                 return ServerResponse;
354         }
355         
356         // Process the first response.
357         
358         string UserPrincipalURI = GetUserPrincipalURI();
359         
360         // Cleanup and reset for the second connection.
361         
362         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
363         ResetResults();
365         ServerAddressURL = BuildURL(UserPrincipalURI);
366         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
367         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
368         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, AddressBookHomeXMLQuery);
369         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(AddressBookHomeXMLQuery));
370         
371         if (TestMode == true){
372                 SessionResult = curl_easy_perform(ConnectionSession);
373         } else {
374                 
375         }
376         
377         switch(SessionResult){
378                 case CURLE_OK:
379                         SSLStatus = true;
380                         SSLVerified = COSSL_VERIFIED;
381                         break;
382                 case CURLE_SSL_CACERT:
383                 case CURLE_SSL_CONNECT_ERROR:
384                         SSLStatus = true;
385                         SSLVerified = COSSL_UNABLETOVERIFY;
386                         break;
387                 default:
388                         break;
389         };
390         
391         SessionResponseCode = 0;
392         
393         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
394         
395         if (SessionResponseCode == 200 || SessionResponseCode == 207){
396                 //ConnectResult = COCONNECT_OK;
397                 AuthPassed = true;
398                 ValidResponse = true;
399         } else if (SessionResponseCode == 403){
400                 //ConnectResult = COCONNECT_AUTHFAIL;
401                 AuthPassed = false;
402                 ValidResponse = true;
403         } else if (SessionResponseCode >= 200) {
404                 //ConnectResult = COCONNECT_INVALID;
405                 AuthPassed = false;
406                 ValidResponse = true;
407         } else {
408                 //ConnectResult = COCONNECT_INVALID;
409                 AuthPassed = false;
410                 ValidResponse = false;                  
411         }
412         
413         if (ValidResponse == false && AuthPassed == false){
414                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
415                 ServerResponse.EntityTag = "";
416                 ServerResponse.SessionCode = SessionResult;
417                 ServerResponse.ResultCode = SessionResponseCode;
418                 ServerResponse.ResultMessage = "";
419                 return ServerResponse;
420         }
421         
422         // Process the second response.
423         
424         string AddressBookHomeURI = GetAddressBookHomeURI();
425         
426         // Cleanup and reset for the second connection.
427         
428         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
429         ResetResults();
430         
431         ServerAddressURL = BuildURL(AddressBookHomeURI);
432         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
433         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
434         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, DefaultAddressBookXMLQuery);
435         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(DefaultAddressBookXMLQuery));
436         
437         if (TestMode == true){
438                 SessionResult = curl_easy_perform(ConnectionSession);
439         } else {
440                 
441         }
442         
443         switch(SessionResult){
444                 case CURLE_OK:
445                         SSLStatus = true;
446                         SSLVerified = COSSL_VERIFIED;
447                         break;
448                 case CURLE_SSL_CACERT:
449                 case CURLE_SSL_CONNECT_ERROR:
450                         SSLStatus = true;
451                         SSLVerified = COSSL_UNABLETOVERIFY;
452                         break;
453                 default:
454                         break;
455         };
456         
457         SessionResponseCode = 0;
458         
459         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
460         
461         if (SessionResponseCode == 200 || SessionResponseCode == 207){
462                 AuthPassed = true;
463                 ValidResponse = true;
464         } else if (SessionResponseCode == 403){
465                 AuthPassed = false;
466                 ValidResponse = true;
467         } else if (SessionResponseCode >= 200) {
468                 AuthPassed = false;
469                 ValidResponse = true;
470         } else {
471                 AuthPassed = false;
472                 ValidResponse = false;                  
473         }
474         
475         if (ValidResponse == false && AuthPassed == false){
476                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
477                 ServerResponse.EntityTag = "";
478                 ServerResponse.SessionCode = SessionResult;
479                 ServerResponse.ResultCode = SessionResponseCode;
480                 ServerResponse.ResultMessage = "";
481                 return ServerResponse;
482         }
483         
484         // Process the second response.
485         
486         (*ServerPrefix) = GetDefaultAddressBookURI();
487         
488         CanProcess = true;
489         
490         ServerResponse.RequestResult = COREQUEST_OK;
491         ServerResponse.EntityTag = "";
492         ServerResponse.SessionCode = SessionResult;
493         ServerResponse.ResultCode = SessionResponseCode;
494         ServerResponse.ResultMessage = SessionErrorBuffer;
495         return ServerResponse;
496         
499 std::string CardDAV2::GetUserPrincipalURI(){
500         
501         xmlDocPtr xmlCardDAVDoc;
502         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
503         string UserPrincipalURI = "";
504         
505         xmlNodePtr nodeLevel1;
506         xmlNodePtr nodeLevel2;
507         xmlNodePtr nodeLevel3;
508         xmlNodePtr nodeLevel4;
509         xmlNodePtr nodeLevel5;
510         xmlNodePtr nodeLevel6;
511         xmlNodePtr nodeLevel7;
512                 
513         for (nodeLevel1 = xmlCardDAVDoc->children;
514                 nodeLevel1 != NULL;
515                 nodeLevel1 = nodeLevel1->next)
516         {
518                 for (nodeLevel2 = nodeLevel1->children;
519                         nodeLevel2 != NULL;
520                         nodeLevel2 = nodeLevel2->next)
521                 {
524                         for (nodeLevel3 = nodeLevel2->children;
525                         nodeLevel3 != NULL;
526                         nodeLevel3 = nodeLevel3->next)
527                         {
528                         
529                                 for (nodeLevel4 = nodeLevel3->children;
530                                 nodeLevel4 != NULL;
531                                 nodeLevel4 = nodeLevel4->next)
532                                 {
533                         
534                                         for (nodeLevel5 = nodeLevel4->children;
535                                         nodeLevel5 != NULL;
536                                         nodeLevel5 = nodeLevel5->next)
537                                         {
538                         
539                                                 for (nodeLevel6 = nodeLevel5->children;
540                                                 nodeLevel6 != NULL;
541                                                 nodeLevel6 = nodeLevel6->next)
542                                                 {
543                         
544                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
545                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
546                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
547                                                         ){
548                         
549                                                                 // Found the <href> part so extract the principal URL address.
550                                                                 
551                                                                 for (nodeLevel7 = nodeLevel6->children;
552                                                                 nodeLevel7 != NULL;
553                                                                 nodeLevel7 = nodeLevel7->next)
554                                                                 {
555                                                                 
556                                                                         UserPrincipalURI = ((const char*)nodeLevel7->content);
558                                                                 }
559                         
560                                                         }
561                         
562                                                 }
563                         
564                                         }
565                         
566                                 }
567                         
568                         }
569                 
570                 }
571                 
572         }
573         
574         xmlFreeDoc(xmlCardDAVDoc);
575         
576         return UserPrincipalURI;
577         
580 std::string CardDAV2::GetAddressBookHomeURI(){
581         
582         xmlDocPtr xmlCardDAVDoc;
583         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
584         string AddressBookHomeURI = "";
585         
586         xmlNodePtr nodeLevel1;
587         xmlNodePtr nodeLevel2;
588         xmlNodePtr nodeLevel3;
589         xmlNodePtr nodeLevel4;
590         xmlNodePtr nodeLevel5;
591         xmlNodePtr nodeLevel6;
592         xmlNodePtr nodeLevel7;
593                 
594         for (nodeLevel1 = xmlCardDAVDoc->children;
595                 nodeLevel1 != NULL;
596                 nodeLevel1 = nodeLevel1->next)
597         {
599                 for (nodeLevel2 = nodeLevel1->children;
600                         nodeLevel2 != NULL;
601                         nodeLevel2 = nodeLevel2->next)
602                 {
605                         for (nodeLevel3 = nodeLevel2->children;
606                         nodeLevel3 != NULL;
607                         nodeLevel3 = nodeLevel3->next)
608                         {
609                         
610                                 for (nodeLevel4 = nodeLevel3->children;
611                                 nodeLevel4 != NULL;
612                                 nodeLevel4 = nodeLevel4->next)
613                                 {
614                         
615                                         for (nodeLevel5 = nodeLevel4->children;
616                                         nodeLevel5 != NULL;
617                                         nodeLevel5 = nodeLevel5->next)
618                                         {
619                         
620                                                 for (nodeLevel6 = nodeLevel5->children;
621                                                 nodeLevel6 != NULL;
622                                                 nodeLevel6 = nodeLevel6->next)
623                                                 {
624                         
625                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
626                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
627                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
628                                                         ){
629                         
630                                                                 // Found the <href> part so extract the principal URL address.
631                                                                 
632                                                                 for (nodeLevel7 = nodeLevel6->children;
633                                                                 nodeLevel7 != NULL;
634                                                                 nodeLevel7 = nodeLevel7->next)
635                                                                 {
636                                                                 
637                                                                         AddressBookHomeURI = ((const char*)nodeLevel7->content);
639                                                                 }
640                         
641                                                         }
642                         
643                                                 }
644                         
645                                         }
646                         
647                                 }
648                         
649                         }
650                 
651                 }
652                 
653         }
654         
655         xmlFreeDoc(xmlCardDAVDoc);
656         
657         return AddressBookHomeURI;
658         
661 std::string CardDAV2::GetDefaultAddressBookURI(){
662         
663         xmlDocPtr xmlCardDAVDoc;
664         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
665         string DefaultAddressBookURI = "";
666         
667         xmlNodePtr nodeLevel1;
668         xmlNodePtr nodeLevel2;
669         xmlNodePtr nodeLevel3;
670         xmlNodePtr nodeLevel4;
671         xmlNodePtr nodeLevel5;
672         xmlNodePtr nodeLevel6;
673         xmlNodePtr nodeLevel7;
674                 
675         for (nodeLevel1 = xmlCardDAVDoc->children;
676                 nodeLevel1 != NULL;
677                 nodeLevel1 = nodeLevel1->next)
678         {
680                 for (nodeLevel2 = nodeLevel1->children;
681                         nodeLevel2 != NULL;
682                         nodeLevel2 = nodeLevel2->next)
683                 {
686                         for (nodeLevel3 = nodeLevel2->children;
687                         nodeLevel3 != NULL;
688                         nodeLevel3 = nodeLevel3->next)
689                         {
690                         
691                                 for (nodeLevel4 = nodeLevel3->children;
692                                 nodeLevel4 != NULL;
693                                 nodeLevel4 = nodeLevel4->next)
694                                 {
695                         
696                                         for (nodeLevel5 = nodeLevel4->children;
697                                         nodeLevel5 != NULL;
698                                         nodeLevel5 = nodeLevel5->next)
699                                         {
700                         
701                                                 for (nodeLevel6 = nodeLevel5->children;
702                                                 nodeLevel6 != NULL;
703                                                 nodeLevel6 = nodeLevel6->next)
704                                                 {
705                         
706                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
707                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
708                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
709                                                         ){
710                         
711                                                                 // Found the <href> part so extract the principal URL address.
712                                                                 
713                                                                 for (nodeLevel7 = nodeLevel6->children;
714                                                                 nodeLevel7 != NULL;
715                                                                 nodeLevel7 = nodeLevel7->next)
716                                                                 {
717                                                                 
718                                                                         DefaultAddressBookURI = ((const char*)nodeLevel7->content);
720                                                                 }
721                         
722                                                         }
723                         
724                                                 }
725                         
726                                         }
727                         
728                                 }
729                         
730                         }
731                 
732                 }
733                 
734         }
735         
736         xmlFreeDoc(xmlCardDAVDoc);
737         
738         return DefaultAddressBookURI;
739         
742 COServerResponse CardDAV2::AddContact(std::string Location, std::string Data){
743         
746 COServerResponse CardDAV2::EditContact(std::string Location, std::string Data){
747         
750 COServerResponse CardDAV2::DeleteContact(std::string Location, std::string EntityTag){
751         
754 COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){
755         
758 COServerResponse CardDAV2::GetContact(std::string Location){
759         
762 COContactList CardDAV2::GetContactList(std::string SyncToken){
763         
765         
766 bool CardDAV2::CanDoProcessing(){
767         return CanProcess;
770 bool CardDAV2::CanDoSSL(){
771         return SSLStatus;
774 COSSLVerified CardDAV2::SSLVerify(){
775         return SSLVerified;
778 bool CardDAV2::AbleToLogin(){
779         return AuthPassed;
782 bool CardDAV2::HasValidResponse(){
783         return ValidResponse;
786 bool CardDAV2::IsSelfSigned(){
787         return SSLSelfSigned;
790 void CardDAV2::SetupDefaultParametersNonSSL(bool DoAuthentication){
791         
792         std::string ServerAddress = "";
794         string ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + "/";
795         string UsernamePassword = ServerUser + ":" + ServerPass;
796         
797         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddress.c_str());
798         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
799         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
800         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
801         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
802         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
803         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
804         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
805         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
806         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
807         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
808         
809         if (DoAuthentication == true){
810                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
811         } else {
812                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
813         }
814         
817 void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
818         
819         // Setup the default parameters.
820         
821         string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
822         string UsernamePassword = ServerUser + ":" + ServerPass;
823         
824         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
825         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
826         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
827         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
828         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
829         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
830         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
831         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
832         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
833         curl_easy_setopt(ConnectionSession, CURLOPT_ERRORBUFFER, SessionErrorBuffer);
834         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
835         curl_easy_setopt(ConnectionSession, CURLOPT_CERTINFO, 1);
836         curl_easy_setopt(ConnectionSession, CURLOPT_VERBOSE, 1);
837         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
838         
839         if (DoAuthentication == true){
840                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
841         } else {
842                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
843         }
844         
845         if (EnableSSLBypass == true){
846                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 0);
847                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 0);
848         } else {
849                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 2);
850                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 1);         
851         }
852         
855 string CardDAV2::BuildURL(string URI){
856         
857         string ServerAddressURL;
858         
859         if (SSLStatus == true){
860                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;      
861         } else {
862                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;
863         }
864         
865         return ServerAddressURL;
866         
869 string CardDAV2::GetErrorMessage(){
870         
871         ErrorMessage = SessionErrorBuffer;      
872         return ErrorMessage;
873         
876 void CardDAV2::ResetResults(){
877         
878         SSLStatus = false;
879         COSSLVerified SSLVerified = COSSL_NORESULT;
880         ValidResponse = false;
881         AuthPassed = false;
882         CanProcess = false;
883         SSLSelfSigned = false;
884         TaskCompleted = false;
885         ErrorMessage = "";
886         SessionErrorBuffer[0] = '\0';
887         PageData = "";
888         PageHeader = "";
889         
892 vector<string> CardDAV2::GetDAVHeader(){
893         
894         // Go through each of the lines looking for the
895         // 'DAV:' section.
896         
897         
898         string HeaderName;
899         string HeaderValue;
900         bool DAVFound = false;
901         bool FastForward = false;
902         vector<string> DAVHeaderList;
903         
904         for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
905                 
906                 if (FastForward == true){
907                         
908                         if (PageHeader[HeaderSeek] == '\n'){
909                                 FastForward = false;
910                         }
911                         
912                         continue;
913                         
914                 }
915                 
916                 try {
917                         PageHeader.substr(HeaderSeek, 4) == "DAV:";
918                 }
919                 
920                 catch (const out_of_range &oor){
921                         break;
922                 }
923                 
924                 if (PageHeader.substr(HeaderSeek, 4) == "DAV:"){
925                         
926                         int CharacterSeek = 5;
927                         
928                         while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
929                                 
930                                 if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
931                                         break;
932                                 }
933                                 
934                                 HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
935                                 CharacterSeek++;
936                         }
937                         
938                         break;
939                         
940                 } else {
941                         
942                         FastForward = true;
943                         continue;
944                         
945                 }
946                 
947                 if (PageHeader[HeaderSeek] == '\n'){
948                         HeaderName = "";
949                 }
950                 
951                 //HeaderName += PageHeader.substr(HeaderSeek, 1);
952                 
953         }
954         
955         // Split the header data.
956         
957         std::string DAVHeaderValue;
958         
959         for (int HeaderSeek = 0; HeaderSeek < HeaderValue.size(); HeaderSeek++){
960                 
961                 if (HeaderValue.substr(HeaderSeek, 1) == ","){
962                         DAVHeaderList.push_back(DAVHeaderValue);
963                         DAVHeaderValue = "";
964                         HeaderSeek++;
965                         continue;
966                 }
967                 
968                 DAVHeaderValue += HeaderValue[HeaderSeek];
969                 
970         }
971         
972         if (DAVHeaderValue.size() > 0){
973                 
974                 DAVHeaderList.push_back(DAVHeaderValue);
975                 
976         }
977         
978         return DAVHeaderList;
979         
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