Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
4b08fbb6174b205df306bb02863a8124e2ac08e0
[xestiaab/.git] / source / carddav / carddav.cpp
1 #include "carddav.h"\r
2 #include "../version.h"\r
3 #include <wx/wx.h>\r
4 #include <wx/tokenzr.h>\r
5 #include <wx/ffile.h>\r
6 #include <libxml/parser.h>\r
7 #include <libxml/tree.h>\r
8 #include <map>\r
9 #include <thread>\r
10 #include "../vcard/vcard.h"\r
11 #include "../common/dirs.h"\r
12 \r
13 size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){\r
14         \r
15         wxString Data;\r
16         Data = wxString::FromUTF8((char *)ptr);\r
17         \r
18         stream->Append(Data);\r
19         \r
20         return size * nmemb;\r
21 \r
22 }\r
23 \r
24 struct UploadDataStruc{\r
25         wxString *readptr;\r
26         long sizeleft;\r
27         int seek = 0;\r
28 };\r
29 \r
30 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){\r
31 \r
32         int ProgressRet;\r
33         \r
34         CardDAV *IncCardDAV = static_cast<CardDAV*>(clientdata);\r
35         ProgressRet = IncCardDAV->ProgressFuncProc(clientdata, TTDown, NDown, TTUp, NUp);\r
36         if (ProgressRet != 0){\r
37                 return 1;\r
38         }\r
39         return 0;\r
40 \r
41 }\r
42 \r
43 wxString CardDAV::ServerAddress;\r
44 int CardDAV::ServerPort;\r
45 wxString CardDAV::ServerUser;\r
46 wxString CardDAV::ServerPass;\r
47 wxString CardDAV::ServerPrefix;\r
48 wxString CardDAV::ServerAccount;\r
49 bool CardDAV::ServerSSL;\r
50 bool *CardDAV::ServerResult;\r
51 bool *CardDAV::ServerMonitor;\r
52 bool CardDAV::SSLStatus;\r
53 bool CardDAV::SSLVerified;\r
54 bool CardDAV::ValidResponse;\r
55 bool CardDAV::AuthPassed;\r
56 bool CardDAV::HasCalDAVSupport;\r
57 bool CardDAV::AbortConnection;\r
58 wxString CardDAV::ServerResponse;\r
59 wxString CardDAV::ServerMethod;\r
60 wxString CardDAV::ServerFilenameLocation;\r
61 wxString CardDAV::ServerUploadData;\r
62 wxString CardDAV::ETagData;\r
63 wxString CardDAV::ETagResult;\r
64 bool CardDAV::UploadMode;\r
65 bool CardDAV::EditMode;\r
66 long CardDAV::ItemIndex;\r
67 std::map<int, int> *CardDAV::ActivityListPtr;\r
68 char CardDAV::curlerrbuffer[CURL_ERROR_SIZE];\r
69 SSLCertCollection CardDAV::SSLCertCol;\r
70 int CardDAV::SSLErrorCode;\r
71 int CardDAV::ConnectionErrorCode;\r
72 wxString CardDAV::PageHeader;\r
73 wxString CardDAV::PageData;\r
74 CURLcode CardDAV::claconncode;\r
75 int CardDAV::HTTPErrorCode;\r
76 wxString CardDAV::ErrorMessage;\r
77 SSLCertCollection CardDAV::VerifyCertCollection;\r
78 \r
79 CardDAV::CardDAV(){\r
80         ServerPort = 8080;\r
81         SSLStatus = FALSE;\r
82         SSLVerified = FALSE;\r
83         AuthPassed = FALSE;\r
84         ValidResponse = FALSE;\r
85         HasCalDAVSupport = FALSE;\r
86         SSLCertCol.SuccessCode = 0;\r
87 \r
88         AbortConnection = FALSE;\r
89         UploadMode = FALSE;\r
90         EditMode = FALSE;\r
91         HTTPErrorCode = 0;\r
92 }\r
93 \r
94 CardDAV::~CardDAV(){\r
95 \r
96 }\r
97 \r
98 size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata){\r
99 \r
100         struct UploadDataStruc *UploadPtr = (struct UploadDataStruc *)userdata;\r
101 \r
102         if (UploadPtr->sizeleft){\r
103 \r
104                 //MeepMoop->sizeleft--;\r
105                 //return 1;\r
106 \r
107                 UploadPtr->sizeleft--;\r
108                 wxString wxSChar;\r
109 \r
110                 wxSChar = UploadPtr->readptr->Mid(UploadPtr->seek,1);\r
111 \r
112                 //*(char *)ptr = (char)wxSChar.mb_str();\r
113 \r
114                 strncpy((char *)ptr, (const char*)wxSChar.mb_str(wxConvUTF8), 1);\r
115 \r
116                 UploadPtr->seek++;\r
117 \r
118                 return 1;\r
119 \r
120         }\r
121 \r
122         return 0;\r
123 \r
124 }\r
125 \r
126 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL){\r
127 \r
128         ServerAddress = SvrAddress;\r
129         ServerPort = SvrPort;\r
130         ServerUser = SvrUser;\r
131         ServerPass = SvrPass;\r
132         ServerSSL = SvrSSL;\r
133         \r
134         return TRUE;\r
135 \r
136 }\r
137 \r
138 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL, wxString SvrPrefix, wxString SvrAccount){\r
139 \r
140         ServerAddress = SvrAddress;\r
141         ServerPort = SvrPort;\r
142         ServerUser = SvrUser;\r
143         ServerPass = SvrPass;\r
144         ServerSSL = SvrSSL;\r
145         ServerPrefix = SvrPrefix;\r
146         ServerAccount = SvrAccount;\r
147 \r
148         return TRUE;\r
149 \r
150 }\r
151 \r
152 bool CardDAV::SetupResultBools(bool *SvrResult, bool *SvrMonitor){\r
153 \r
154         ServerResult = SvrResult;\r
155         ServerMonitor = SvrMonitor;\r
156 \r
157         return TRUE;\r
158 \r
159 }\r
160 \r
161 bool CardDAV::HasValidResponse(){\r
162 \r
163         return ValidResponse;\r
164 \r
165 }\r
166 \r
167 bool CardDAV::CanDoCardDAV(){\r
168 \r
169         return HasCalDAVSupport;\r
170 \r
171 }\r
172 \r
173 bool CardDAV::CanDoSSL(){\r
174 \r
175         return SSLStatus;\r
176 \r
177 }\r
178 \r
179 bool CardDAV::SSLVerify(){\r
180 \r
181         return SSLVerified;\r
182 \r
183 }\r
184 \r
185 bool CardDAV::AbleToLogin(){\r
186 \r
187         return AuthPassed;\r
188 \r
189 }\r
190 \r
191 /*\r
192 \r
193 size_t CardDAV::WritebackFunc(char *ptr, size_t size, size_t nmemb, FILE *stream){\r
194 \r
195         wxString Data;\r
196         Data = wxString::FromUTF8((char *)ptr);\r
197         if ((bool)stream == TRUE){\r
198                 PageHeader.Append(Data);\r
199         } else {\r
200                 PageData.Append(Data);\r
201         }\r
202         return size * nmemb;\r
203 \r
204 }\r
205 \r
206 */\r
207 \r
208 int CardDAV::ProgressFuncProc(void *clientdata, double TTUp, double NUp, double TTDown, double NDown){\r
209 \r
210         if (AbortConnection == TRUE){\r
211         \r
212                 return -1;\r
213         \r
214         } else {\r
215         \r
216                 return 0;\r
217         \r
218         }\r
219 \r
220 }\r
221 \r
222 void CardDAV::Abort(){\r
223 \r
224         AbortConnection = TRUE;\r
225 \r
226 }\r
227 \r
228 CURLcode CardDAV::SSLVerifyTest(){\r
229 \r
230         PageData.Clear();\r
231         PageHeader.Clear();\r
232 \r
233         SSLStatus = TRUE;\r
234         AuthPassed = TRUE;\r
235         AbortConnection = FALSE;\r
236 \r
237         CURL *conn;\r
238         CURL *connssldata;\r
239         CURLcode conncode;\r
240         wxString ServerAddressURL;\r
241         wxString ServerAuth;\r
242         wxString ServerAddressSSL;\r
243         wxString ServerAddressNormal;\r
244 \r
245         conn = curl_easy_init();\r
246 \r
247         /*struct CardDAVCURLPasser {\r
248 \r
249                 CardDAV *Data;\r
250                 bool HeaderMode = TRUE;\r
251 \r
252         } CardDAVHeader, CardDAVFooter;\r
253 \r
254         CardDAVHeader.Data = this;\r
255         CardDAVHeader.HeaderMode = TRUE;\r
256 \r
257         CardDAVFooter.Data = this;\r
258         CardDAVFooter.HeaderMode = FALSE;*/\r
259 \r
260         wxString Data1;\r
261         wxString Data2;\r
262 \r
263         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
264         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
265 \r
266         if (ServerSSL){\r
267 \r
268                 union {\r
269                         struct curl_slist       *certdata;\r
270                         struct curl_certinfo    *certinfo;\r
271                 } ptr;\r
272 \r
273                 ptr.certdata = NULL;\r
274 \r
275                 // Setup two initial connections and attempt to get the certificate data.\r
276 \r
277                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
278                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
279                 curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L);\r
280                 //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE);\r
281                 //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE);\r
282                 curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer);\r
283                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
284                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
285                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
286 \r
287                 conncode = (curl_easy_perform(conn));\r
288 \r
289                 // Check if the SSL certificate is valid or self-signed or some other\r
290                 // error occured.\r
291 \r
292                 if (conncode == CURLE_OK){\r
293 \r
294                         // Connection is OK. Do nothing.\r
295 \r
296                         *ServerResult = TRUE;\r
297 \r
298                 } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){\r
299 \r
300                         connssldata = curl_easy_init();\r
301 \r
302                         // Retry but get the certificates without peer/host verification.\r
303 \r
304                         curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
305                         curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1);\r
306                         curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L);\r
307                         //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE);\r
308                         //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE);\r
309                         curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer);\r
310                         curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
311                         curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData);\r
312                         curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader);\r
313                         //curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, FALSE);\r
314                         //curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, FALSE);\r
315 \r
316                         CURLcode certfetchcode;\r
317 \r
318                         certfetchcode = (curl_easy_perform(connssldata));\r
319 \r
320                         VerifyCertCollection = BuildSSLCollection(connssldata);\r
321 \r
322                         if (certfetchcode == CURLE_OK){\r
323                                 \r
324                                 curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata);\r
325 \r
326                                 VerifyCertCollection = BuildSSLCollection(connssldata);\r
327 \r
328                         } else {\r
329 \r
330                                 conncode = certfetchcode;\r
331 \r
332                         }\r
333 \r
334                         *ServerResult = FALSE;\r
335 \r
336                 } else {\r
337 \r
338                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
339                                 curl_easy_strerror(conncode));\r
340 \r
341                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
342 \r
343                         *ServerResult = FALSE;\r
344 \r
345                 }\r
346 \r
347         }\r
348 \r
349         curl_easy_cleanup(conn);\r
350 \r
351         return conncode;\r
352 \r
353 }\r
354 \r
355 SSLCertCollection CardDAV::GetSSLVerifyResults(){\r
356         return VerifyCertCollection;\r
357 }\r
358 \r
359 bool CardDAV::Connect(){\r
360 \r
361         PageData.Clear();\r
362         PageHeader.Clear();\r
363 \r
364         SSLStatus = TRUE;\r
365         AuthPassed = TRUE;\r
366         AbortConnection = FALSE;\r
367 \r
368     CURL *conn;\r
369     CURLcode conncode;\r
370         wxString ServerAddressURL;\r
371         wxString ServerAuth;\r
372         wxString ServerAddressSSL;\r
373         wxString ServerAddressNormal;   \r
374 \r
375         conn = curl_easy_init();\r
376 \r
377         struct CardDAVCURLPasser {\r
378         \r
379                 CardDAV *Data;\r
380                 bool HeaderMode = TRUE;\r
381         \r
382         } CardDAVHeader, CardDAVFooter;\r
383 \r
384         CardDAVHeader.Data = this;\r
385         CardDAVHeader.HeaderMode = TRUE;\r
386         \r
387         CardDAVFooter.Data = this;\r
388         CardDAVFooter.HeaderMode = FALSE;\r
389 \r
390         wxString Data1;\r
391         wxString Data2;\r
392         \r
393         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
394         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
395         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
396         \r
397         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
398         \r
399         // Try SSL first.\r
400 \r
401 \r
402         /*\r
403         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
404         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
405         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
406         \r
407         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
408         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
409         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
410 \r
411         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
412         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
413         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
414         \r
415         */\r
416         \r
417         if (ServerSSL){\r
418 \r
419                 union {\r
420                         struct curl_slist       *certdata;\r
421                         struct curl_certinfo    *certinfo;\r
422                 } ptr;\r
423 \r
424                 ptr.certdata = NULL;\r
425 \r
426                 // Setup two initial connections and attempt to get the certificate data.\r
427 \r
428                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
429                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
430 \r
431                 conncode = (curl_easy_perform(conn));\r
432 \r
433                 // Check if the SSL certificate is valid or self-signed or some other\r
434                 // error occured.\r
435 \r
436                 if (conncode == CURLE_OK){\r
437 \r
438                         // Connection is OK. Do nothing.\r
439 \r
440                 } else if (conncode == CURLE_SSL_CACERT){\r
441 \r
442                         // Post message saying SSL certificate is invalid and \r
443 \r
444 \r
445                         curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);\r
446 \r
447                 } else {\r
448 \r
449                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
450                                 curl_easy_strerror(conncode));\r
451 \r
452                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
453 \r
454                         *ServerResult = FALSE;\r
455                         return FALSE;\r
456 \r
457                 }\r
458 \r
459                 /*curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
460                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
461                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
462                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
463                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
464                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
465                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
466                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
467                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
468                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
469                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
470                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
471 \r
472                 conncode = (curl_easy_perform(conn));\r
473 \r
474                 union {\r
475                         struct curl_slist       *certdata;\r
476                         struct curl_certinfo    *certinfo;\r
477                 } ptr;\r
478                 \r
479                 ptr.certdata = NULL;\r
480 \r
481                 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);\r
482                 \r
483                 if (conncode == CURLE_OK){\r
484 \r
485                         // Process the server header response and look for\r
486                         // 'addressbook' within the DAV header.\r
487 \r
488                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
489                         wxString wxSHeaderLine;\r
490                         std::map<int, wxString> DAVHeaderLines;\r
491 \r
492                         while (wxSHeaderLines.HasMoreTokens()){\r
493 \r
494                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
495 \r
496                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
497 \r
498                                         // Look for address book in the line.\r
499 \r
500                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
501 \r
502                                                 HasCalDAVSupport = TRUE;\r
503 \r
504                                         }\r
505 \r
506                                 }\r
507 \r
508                         }\r
509 \r
510                         *ServerResult = TRUE;\r
511                         AuthPassed = TRUE;\r
512                         SSLStatus = TRUE;\r
513                         return TRUE;\r
514 \r
515                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
516                 \r
517                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
518                                         curl_easy_strerror(conncode));\r
519                                 \r
520                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
521 \r
522                         *ServerResult = TRUE;\r
523                         ValidResponse = FALSE;\r
524                         AuthPassed = FALSE;\r
525                         SSLStatus = TRUE;\r
526                         return TRUE;\r
527                 \r
528                 } else {\r
529 \r
530                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
531                                         curl_easy_strerror(conncode));\r
532 \r
533                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
534 \r
535                         *ServerResult = FALSE;\r
536                         return FALSE;                                   \r
537 \r
538                 }\r
539 \r
540         } else {\r
541         \r
542         // No SSL.\r
543                 \r
544                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
545                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
546                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
547                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);    \r
548                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
549                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
550                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
551                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
552                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
553                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
554                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
555 \r
556                 conncode = (curl_easy_perform(conn));\r
557 \r
558                 if (conncode == CURLE_OK){\r
559 \r
560                         // Process the server header response and look for\r
561                         // 'addressbook' within the DAV header.\r
562                         \r
563                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
564                         wxString wxSHeaderLine;\r
565                         std::map<int, wxString> DAVHeaderLines;\r
566                         \r
567                         while (wxSHeaderLines.HasMoreTokens()){\r
568                         \r
569                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
570                                 \r
571                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
572                                 \r
573                                         // Look for address book in the line.\r
574                                         \r
575                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
576                                         \r
577                                                 HasCalDAVSupport = TRUE;\r
578                                         \r
579                                         }\r
580                                 \r
581                                 }\r
582                         \r
583                         }\r
584 \r
585                         *ServerResult = TRUE;\r
586                         ValidResponse = TRUE;                   \r
587                         AuthPassed = TRUE;\r
588                         SSLStatus = FALSE;\r
589                         return TRUE;\r
590 \r
591                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
592                 \r
593                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
594                                         curl_easy_strerror(conncode));\r
595                                         \r
596                         *ServerResult = TRUE;\r
597                         ValidResponse = FALSE;\r
598                         AuthPassed = FALSE;\r
599                         SSLStatus = FALSE;\r
600                         return TRUE;\r
601                 \r
602                 } else {\r
603 \r
604                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
605                                         curl_easy_strerror(conncode));\r
606                                 \r
607                         *ServerResult = FALSE;\r
608                         return FALSE;\r
609 \r
610                 }\r
611                 \r
612                 // TODO: Double check and make sure HTTP Authentication is possible.\r
613                 \r
614         }               \r
615                 \r
616         *ServerResult = TRUE;\r
617         return TRUE;    \r
618 \r
619 }\r
620 \r
621 void CardDAV::GetSSLResults(){\r
622 \r
623         \r
624 \r
625 }\r
626 \r
627 void CardDAV::ProcessDataThread(){\r
628 \r
629         PageData.Clear();\r
630         PageHeader.Clear();\r
631 \r
632         SSLStatus = TRUE;\r
633         AuthPassed = TRUE;\r
634         AbortConnection = FALSE;\r
635 \r
636         CURL *conn;\r
637         CURLcode conncode;\r
638         wxString ServerAddressURL;\r
639         wxString ServerAuth;\r
640         wxString ServerAddressSSL;\r
641         wxString ServerAddressNormal;   \r
642 \r
643         conn = curl_easy_init();\r
644         \r
645         struct CardDAVCURLPasser {\r
646         \r
647                 CardDAV *Data;\r
648                 bool HeaderMode = TRUE;\r
649         \r
650         } CardDAVHeader, CardDAVFooter;\r
651 \r
652         CardDAVHeader.Data = this;\r
653         CardDAVHeader.HeaderMode = TRUE;\r
654         \r
655         CardDAVFooter.Data = this;\r
656         CardDAVFooter.HeaderMode = FALSE;\r
657 \r
658         wxString Data1;\r
659         wxString Data2;\r
660         \r
661         wxString ETag;\r
662         wxString ETagOriginal;\r
663         wxString ETagServer;\r
664                 \r
665         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
666         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
667         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
668         \r
669         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
670         \r
671         // Try SSL first.\r
672 \r
673 \r
674         /*\r
675         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
676         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
677         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
678         \r
679         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
680         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
681         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
682 \r
683         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
684         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
685         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
686         \r
687         */\r
688 \r
689         //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
690 \r
691         std::map<int,int>::iterator ActIter;\r
692         struct UploadDataStruc UploadData;\r
693         \r
694         \r
695         ActIter = ActivityListPtr->find((int)ItemIndex);\r
696         \r
697         // Update result flag.\r
698 \r
699         ActIter->second = 1;\r
700         \r
701         // Setup the request mode if it is not empty.\r
702         \r
703         if (!ServerMethod.IsEmpty()){\r
704         \r
705                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8));\r
706 \r
707         }\r
708 \r
709         if (ServerSSL){\r
710 \r
711                 wxString ServerCertFilename;\r
712                 bool MatchingCert = FALSE;\r
713 \r
714                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
715                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
716                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
717                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
718                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
719                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
720                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
721                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
722                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
723                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
724                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
725                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
726                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
727                 \r
728                 if (UploadMode == TRUE){\r
729                         \r
730                         UploadData.readptr = &ServerUploadData;\r
731                         UploadData.sizeleft = ServerUploadData.Len();\r
732                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
733                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
734                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
735                 \r
736                 }\r
737 \r
738                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
739 \r
740                 if (wxFile::Exists(ServerCertFilename) == TRUE){\r
741                 \r
742                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
743                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
744                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
745                 \r
746                 }\r
747 \r
748                 //UploadData.readptr = &CardDAVDataQuery;\r
749                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
750                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
751                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
752                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
753                 \r
754                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
755                 \r
756                 claconncode = (curl_easy_perform(conn));\r
757 \r
758                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
759                 // the local certificate in use.\r
760 \r
761                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
762                         \r
763                         curl_easy_cleanup(conn);\r
764                         conn = curl_easy_init();\r
765                         \r
766                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
767                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
768                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
769                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
770                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
771                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
772                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
773                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
774                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
775                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
776                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
777                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
778                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
779 \r
780                         if (UploadMode == TRUE){\r
781 \r
782                                 UploadData.readptr = &ServerUploadData;\r
783                                 UploadData.sizeleft = ServerUploadData.Len();\r
784                                 curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
785                                 curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
786                                 curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
787                 \r
788                         }\r
789                         \r
790                         claconncode = (curl_easy_perform(conn));\r
791                         \r
792                         // If claconncode is CURLE_OK then delete the certificate file as that\r
793                         // is no longer needed.\r
794                         \r
795                         if (claconncode == CURLE_OK){\r
796                         \r
797                                 // Delete the certificate file.\r
798                                 \r
799                                 wxRemoveFile(ServerCertFilename);\r
800                         \r
801                         }\r
802                 \r
803                 }\r
804 \r
805                 // Check if it fails with a CURLE_SSL_CACERT then compare\r
806                 // the certificates as PEM files.\r
807                 \r
808                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
809                 \r
810                         //curl_easy_cleanup(conn);\r
811                         //conn = curl_easy_init();\r
812 \r
813                         CURL *sslerrconn;\r
814                         sslerrconn = curl_easy_init();\r
815                         CURLcode sslerrconncode;\r
816 \r
817                         //claconncode = (curl_easy_perform(conn));\r
818 \r
819                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
820 \r
821                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
822                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
823                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
824                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
825                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
826                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
827                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
828                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
829                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
830                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
831                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
832                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
833                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
834                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
835                 \r
836                         wxString SSLLocalData;\r
837                         wxString SSLServerData;\r
838                 \r
839                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
840                 \r
841                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
842                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
843                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
844                         \r
845                         wxFFile SSLLocalFile;\r
846                         \r
847 #if wxABI_VERSION < 20900\r
848                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
849 #else\r
850                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
851 #endif  \r
852         \r
853                         // Load the recovery database for tasks not done.\r
854         \r
855                         if (SSLLocalFile.IsOpened() == TRUE){\r
856 \r
857                         // Check if we are using wxWidgets version 2.8 or less and\r
858                         // execute the required command accordingly.\r
859         \r
860                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
861                 \r
862         \r
863                         }\r
864                         \r
865                         SSLServerData = SSLDataIter->second;\r
866                         \r
867                         if (SSLLocalData == SSLServerData){\r
868                         \r
869                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
870                                 // and CURLOPT_SSL_VERIFYHOST off.\r
871                         \r
872                                 curl_easy_cleanup(conn);\r
873                                 conn = curl_easy_init();\r
874                                 \r
875                                 PageData.clear();\r
876                                 PageHeader.clear();\r
877                         \r
878                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
879                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
880                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
881                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
882                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
883                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
884                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
885                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
886                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
887                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
888                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
889                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
890                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
891 \r
892                                 if (UploadMode == TRUE){\r
893 \r
894                                         UploadData.readptr = &ServerUploadData;\r
895                                         UploadData.sizeleft = ServerUploadData.Len();\r
896                                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
897                                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
898                                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
899                 \r
900                                 }\r
901                                 \r
902                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
903                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
904                         \r
905                                 claconncode = (curl_easy_perform(conn));\r
906                                 \r
907                                 MatchingCert = TRUE;\r
908                         \r
909                         }\r
910                         \r
911                         if (MatchingCert == FALSE){\r
912                 \r
913                                 claconncode = CURLE_SSL_CACERT;\r
914                                 return;\r
915                 \r
916                         }\r
917                         \r
918                         curl_easy_cleanup(sslerrconn);\r
919                 \r
920                 }\r
921 \r
922                 // Sort out SSL error.\r
923                 \r
924                 // When SSL cert error occurs, connect again and fetch certificates.\r
925                 // Display a message to the user explaining that an invalid\r
926                 // certificate has been given and let the user decide what\r
927                 // to do next.\r
928 \r
929                 if (claconncode == CURLE_OK){\r
930 \r
931                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
932                 \r
933                         CURL *sslerrconn;\r
934                         sslerrconn = curl_easy_init();\r
935                         CURLcode sslerrconncode;\r
936                 \r
937                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
938                 \r
939                         // Replace conn with sslerrconn!\r
940                 \r
941                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
942                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
943                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
944                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
945                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
946                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
947                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
948                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
949                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
950                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
951                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
952                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
953                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
954                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
955                 \r
956                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
957 \r
958                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
959                         SSLCertCol.SuccessCode = 1;\r
960 \r
961                         return;\r
962                 \r
963                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
964                 \r
965                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
966                                         curl_easy_strerror(claconncode));\r
967                         int http_code = 0;\r
968                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
969                         fprintf(stderr, "Error code was: %d\n", http_code);\r
970                                         \r
971                         return;\r
972                 \r
973                 } else {\r
974 \r
975                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
976                                         curl_easy_strerror(claconncode));\r
977                         int http_code = 0;\r
978                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
979                         fprintf(stderr, "Error code was: %d\n", http_code);\r
980 \r
981                         return;\r
982 \r
983                 }\r
984 \r
985         } else {\r
986         \r
987         // No SSL.\r
988                 \r
989                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
990                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
991                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
992                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
993                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
994                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
995                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
996                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
997                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
998                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
999                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
1000                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1001                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1002                 \r
1003                 if (UploadMode == TRUE){\r
1004                         \r
1005                         UploadData.readptr = &ServerUploadData;\r
1006                         UploadData.sizeleft = ServerUploadData.Len();\r
1007                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1008                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1009                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1010                 \r
1011                 }\r
1012                 \r
1013                 conncode = (curl_easy_perform(conn));\r
1014 \r
1015                 if (conncode == CURLE_OK){\r
1016 \r
1017                         // Process the server header response and look for\r
1018                         // 'addressbook' within the DAV header.\r
1019                         \r
1020                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
1021                         wxString wxSHeaderLine;\r
1022                         std::map<int, wxString> DAVHeaderLines;\r
1023                         \r
1024                         while (wxSHeaderLines.HasMoreTokens()){\r
1025                         \r
1026                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
1027                                 \r
1028                                 if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){\r
1029                                 \r
1030                                         ETagData = wxSHeaderLine.Mid(5);\r
1031                                         ETagData.Trim();\r
1032                                         ETagData.Trim(FALSE);\r
1033                                         \r
1034                                         // Check for commas.\r
1035                                         \r
1036                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
1037                                                         \r
1038                                                 ETagData.Remove(0, 1);\r
1039                                                 ETagData.RemoveLast();\r
1040                                                         \r
1041                                         }\r
1042                                 \r
1043                                 }\r
1044                                 \r
1045                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
1046                                 \r
1047                                         // Look for address book in the line.\r
1048                                         \r
1049                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
1050                                         \r
1051                                                 HasCalDAVSupport = TRUE;\r
1052                                         \r
1053                                         }\r
1054                                 \r
1055                                 }\r
1056                         \r
1057                         }\r
1058                         \r
1059                         // Get the ETag from the header.\r
1060                         \r
1061                         if (UploadMode == TRUE){\r
1062                 \r
1063                                 wxString PageHeaderLine;\r
1064                 \r
1065                                 wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n"));\r
1066                                 \r
1067                                 if (PageHeaderSplit.HasMoreTokens()){\r
1068                                 \r
1069                                         PageHeaderLine = PageHeaderSplit.GetNextToken();\r
1070                                 \r
1071                                 }\r
1072                 \r
1073                         }\r
1074 \r
1075                         ActIter->second = 4;\r
1076                         return;\r
1077 \r
1078                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
1079 \r
1080                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
1081                 \r
1082                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1083                                         curl_easy_strerror(conncode));\r
1084 \r
1085                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
1086                                         GetHTTPCode());\r
1087 \r
1088                         ActIter->second = 2;\r
1089                         return;\r
1090                 \r
1091                 } else {\r
1092 \r
1093                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1094                                         curl_easy_strerror(conncode));\r
1095                                 \r
1096                         ActIter->second = 2;\r
1097                         return;\r
1098 \r
1099                 }\r
1100                 \r
1101         }\r
1102         \r
1103         /*\r
1104         \r
1105         }\r
1106         \r
1107         */\r
1108         \r
1109         // Connection was successful \r
1110                 /*      \r
1111         \r
1112         if (conn){\r
1113                 \r
1114                 wxString ServerAddressURL;\r
1115                 \r
1116                 // Try secure connection first.\r
1117                 \r
1118                 \r
1119                 \r
1120 \r
1121                 ServerAddressURL = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
1122                 \r
1123                 ServerAddressURL.Trim();\r
1124                 \r
1125                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressURL.mb_str(wxConvUTF8));\r
1126                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1127                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, NULL);\r
1128                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, NULL);\r
1129                         \r
1130 \r
1131                 conncode = (curl_easy_perform(conn));\r
1132 \r
1133                 if (conncode == CURLE_OK){\r
1134                         *ServerResult = TRUE;\r
1135                         return TRUE;\r
1136                 \r
1137                 } else {\r
1138 \r
1139                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1140                                 curl_easy_strerror(conncode));                  \r
1141 \r
1142                         *ServerResult = FALSE;\r
1143                         return FALSE;           \r
1144                 }\r
1145 \r
1146                 // Failed. So use unsecure connection.\r
1147                 UseSSL = FALSE;\r
1148                 \r
1149                 ServerAddress = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort);\r
1150                 \r
1151                 curl_easy_setopt(conn, CURLOPT_URL, ServerAddress.c_str());\r
1152         \r
1153                 conncode = (curl_easy_perform(conn));           \r
1154                 \r
1155                 if (conncode != CURLE_OK){\r
1156                         *ServerResult = FALSE;\r
1157                         return FALSE;\r
1158                 } else {\r
1159                         *ServerResult = TRUE;\r
1160                         return TRUE;\r
1161                 }\r
1162         \r
1163         } else {\r
1164         \r
1165                 *ServerResult = FALSE;\r
1166                 return FALSE;\r
1167         \r
1168         }\r
1169         \r
1170                 */\r
1171         \r
1172         // Catch all.\r
1173         \r
1174         ActIter->second = 1;\r
1175         *ServerResult = TRUE;\r
1176         return;\r
1177 \r
1178 }\r
1179 \r
1180 void CardDAV::ProcessData(){\r
1181 \r
1182         std::thread ConnectThread(&CardDAV::ProcessDataThread, this);\r
1183         ConnectThread.detach();\r
1184 \r
1185 }\r
1186 \r
1187 void CardDAV::SetServerFilename(wxString Filename){\r
1188 \r
1189         ServerFilenameLocation = Filename;\r
1190 \r
1191 }\r
1192 \r
1193 void CardDAV::GetServerContactData()\r
1194 {\r
1195 \r
1196         PageData.Clear();\r
1197         PageHeader.Clear();\r
1198 \r
1199         SSLStatus = TRUE;\r
1200         AuthPassed = TRUE;\r
1201         AbortConnection = FALSE;\r
1202         \r
1203         wxString ServerCertFilename;\r
1204         bool MatchingCert = FALSE;\r
1205 \r
1206         CURL *conn;\r
1207         CURLcode conncode;\r
1208         wxString ServerAddressURL;\r
1209         wxString ServerAuth;\r
1210         wxString ServerAddressSSL;\r
1211         wxString ServerAddressNormal;   \r
1212 \r
1213         conn = curl_easy_init();\r
1214         \r
1215         struct CardDAVCURLPasser {\r
1216         \r
1217                 CardDAV *Data;\r
1218                 bool HeaderMode = TRUE;\r
1219         \r
1220         } CardDAVHeader, CardDAVFooter;\r
1221 \r
1222         CardDAVHeader.Data = this;\r
1223         CardDAVHeader.HeaderMode = TRUE;\r
1224         \r
1225         CardDAVFooter.Data = this;\r
1226         CardDAVFooter.HeaderMode = FALSE;\r
1227 \r
1228         wxString Data1;\r
1229         wxString Data2;\r
1230         \r
1231         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
1232         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
1233         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
1234         \r
1235         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
1236         \r
1237         // Try SSL first.\r
1238 \r
1239 \r
1240         /*\r
1241         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
1242         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
1243         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
1244         \r
1245         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
1246         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
1247         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
1248 \r
1249         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
1250         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
1251         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
1252         \r
1253         */\r
1254 \r
1255         //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
1256 \r
1257         std::map<int,int>::iterator ActIter;\r
1258         struct UploadDataStruc UploadData;\r
1259         \r
1260         \r
1261         ActIter = ActivityListPtr->find((int)ItemIndex);\r
1262 \r
1263         //ActIter->second = 1;\r
1264 \r
1265         /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");\r
1266         CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));\r
1267         CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));\r
1268         CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));\r
1269         CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));\r
1270         CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));\r
1271         CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));\r
1272         CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/\r
1273 \r
1274         if (ServerSSL){\r
1275 \r
1276                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1277                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
1278                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1279                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1280                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1281                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
1282                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1283                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1284                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1285                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1286                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1287                 \r
1288                 //UploadData.readptr = &CardDAVDataQuery;\r
1289                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1290                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1291                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1292                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1293 \r
1294                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
1295 \r
1296                 if (wxFile::Exists(ServerCertFilename) == TRUE){\r
1297                 \r
1298                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
1299                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
1300                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
1301                 \r
1302                 }\r
1303 \r
1304                 claconncode = (curl_easy_perform(conn));\r
1305 \r
1306                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
1307                 // the local certificate in use.\r
1308 \r
1309                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
1310                         \r
1311                         curl_easy_cleanup(conn);\r
1312                         conn = curl_easy_init();\r
1313                         \r
1314                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1315                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
1316                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1317                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1318                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1319                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
1320                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1321                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1322                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1323                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1324                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1325                 \r
1326                         //UploadData.readptr = &CardDAVDataQuery;\r
1327                         //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1328                         \r
1329                         claconncode = (curl_easy_perform(conn));\r
1330                         \r
1331                         // If claconncode is CURLE_OK then delete the certificate file as that\r
1332                         // is no longer needed.\r
1333                         \r
1334                         if (claconncode == CURLE_OK){\r
1335                         \r
1336                                 // Delete the certificate file.\r
1337                                 \r
1338                                 wxRemoveFile(ServerCertFilename);\r
1339                         \r
1340                         }\r
1341                 \r
1342                 }\r
1343 \r
1344                 // Check if it fails with a CURLE_SSL_CACERT then compare\r
1345                 // the certificates as PEM files.\r
1346                 \r
1347                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
1348                 \r
1349                         //curl_easy_cleanup(conn);\r
1350                         //conn = curl_easy_init();\r
1351 \r
1352                         CURL *sslerrconn;\r
1353                         sslerrconn = curl_easy_init();\r
1354                         CURLcode sslerrconncode;\r
1355 \r
1356                         //claconncode = (curl_easy_perform(conn));\r
1357 \r
1358                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
1359 \r
1360                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1361                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
1362                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1363                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1364                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1365                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
1366                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1367                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1368                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1369                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1370                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1371                 \r
1372                         //UploadData.readptr = &CardDAVDataQuery;\r
1373                         //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1374                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
1375                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
1376                 \r
1377                         wxString SSLLocalData;\r
1378                         wxString SSLServerData;\r
1379                 \r
1380                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
1381                 \r
1382                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
1383                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
1384                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
1385                         \r
1386                         wxFFile SSLLocalFile;\r
1387                         \r
1388 #if wxABI_VERSION < 20900\r
1389                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
1390 #else\r
1391                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
1392 #endif  \r
1393         \r
1394                         // Load the recovery database for tasks not done.\r
1395         \r
1396                         if (SSLLocalFile.IsOpened() == TRUE){\r
1397 \r
1398                         // Check if we are using wxWidgets version 2.8 or less and\r
1399                         // execute the required command accordingly.\r
1400         \r
1401                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
1402                 \r
1403         \r
1404                         }\r
1405                         \r
1406                         SSLServerData = SSLDataIter->second;\r
1407                         \r
1408                         if (SSLLocalData == SSLServerData){\r
1409                         \r
1410                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
1411                                 // and CURLOPT_SSL_VERIFYHOST off.\r
1412                         \r
1413                                 curl_easy_cleanup(conn);\r
1414                                 conn = curl_easy_init();\r
1415                                 \r
1416                                 PageData.clear();\r
1417                                 PageHeader.clear();\r
1418                         \r
1419                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1420                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
1421                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1422                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1423                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1424                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
1425                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1426                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1427                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1428                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1429                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1430                 \r
1431                                 //UploadData.readptr = &CardDAVDataQuery;\r
1432                                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1433                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
1434                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
1435                                                         \r
1436                                 claconncode = (curl_easy_perform(conn));\r
1437                                 \r
1438                                 MatchingCert = TRUE;\r
1439                         \r
1440                         }\r
1441                         \r
1442                         if (MatchingCert == FALSE){\r
1443                 \r
1444                                 claconncode = CURLE_SSL_CACERT;\r
1445                                 return;\r
1446                 \r
1447                         }\r
1448                         \r
1449                         curl_easy_cleanup(sslerrconn);\r
1450                 \r
1451                 }\r
1452                 \r
1453                 // Sort out SSL error.\r
1454                 \r
1455                 // When SSL cert error occurs, connect again and fetch certificates.\r
1456                 // Display a message to the user explaining that an invalid\r
1457                 // certificate has been given and let the user decide what\r
1458                 // to do next.\r
1459 \r
1460                 if (claconncode == CURLE_OK){\r
1461 \r
1462                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
1463                 \r
1464                         CURL *sslerrconn;\r
1465                         sslerrconn = curl_easy_init();\r
1466                         CURLcode sslerrconncode;\r
1467                 \r
1468                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
1469                 \r
1470                         // Replace conn with sslerrconn!\r
1471                 \r
1472                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
1473                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
1474                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1475                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
1476                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
1477                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1478                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1479                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
1480                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
1481                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
1482                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1483                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
1484                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
1485                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
1486                                         \r
1487                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
1488 \r
1489                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
1490                         SSLCertCol.SuccessCode = 1;\r
1491 \r
1492                         return;\r
1493                 \r
1494                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
1495                 \r
1496                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1497                                         curl_easy_strerror(claconncode));\r
1498                         int http_code = 0;\r
1499                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
1500                         fprintf(stderr, "Error code was: %d\n", http_code);\r
1501                                         \r
1502                         return;\r
1503                 \r
1504                 } else {\r
1505 \r
1506                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1507                                         curl_easy_strerror(claconncode));\r
1508                         int http_code = 0;\r
1509                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
1510                         fprintf(stderr, "Error code was: %d\n", http_code);\r
1511 \r
1512                         return;\r
1513 \r
1514                 }\r
1515         } else {\r
1516         \r
1517                 // No SSL.\r
1518                 \r
1519                 wxString EmptyString;\r
1520                 \r
1521                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
1522                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
1523                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1524                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1525                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1526                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
1527                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1528                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1529                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1530                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1531                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1532                 \r
1533                 //UploadData.readptr = &CardDAVDataQuery;\r
1534                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1535                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1536                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1537                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1538 \r
1539                 //UploadData.readptr = &CardDAVDataQuery;\r
1540                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1541                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1542                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1543                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1544                 \r
1545                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     \r
1546                 \r
1547                 PageData.Clear();\r
1548                 PageHeader.Clear();\r
1549                 \r
1550                 conncode = (curl_easy_perform(conn));\r
1551 \r
1552                 if (conncode == CURLE_OK){\r
1553 \r
1554                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
1555                 \r
1556                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1557                                         curl_easy_strerror(conncode));\r
1558                                         \r
1559                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
1560                                         GetHTTPCode());\r
1561                                         \r
1562                         return;\r
1563                 \r
1564                 } else {\r
1565 \r
1566                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1567                                         curl_easy_strerror(conncode));\r
1568                                 \r
1569                         return;\r
1570 \r
1571                 }\r
1572                 \r
1573         }\r
1574         \r
1575         return;\r
1576 \r
1577 }\r
1578 \r
1579 wxString CardDAV::GetPageData()\r
1580 {\r
1581 \r
1582         return PageData;\r
1583 \r
1584 }\r
1585 \r
1586 void CardDAV::GetServerETagValueThread()\r
1587 {\r
1588 \r
1589         PageData.Clear();\r
1590         PageHeader.Clear();\r
1591 \r
1592         SSLStatus = TRUE;\r
1593         AuthPassed = TRUE;\r
1594         AbortConnection = FALSE;\r
1595 \r
1596         CURL *conn;\r
1597         CURLcode conncode;\r
1598         wxString ServerAddressURL;\r
1599         wxString ServerAuth;\r
1600         wxString ServerAddressSSL;\r
1601         wxString ServerAddressNormal;   \r
1602 \r
1603         conn = curl_easy_init();\r
1604         \r
1605         struct CardDAVCURLPasser {\r
1606         \r
1607                 CardDAV *Data;\r
1608                 bool HeaderMode = TRUE;\r
1609         \r
1610         } CardDAVHeader, CardDAVFooter;\r
1611 \r
1612         CardDAVHeader.Data = this;\r
1613         CardDAVHeader.HeaderMode = TRUE;\r
1614         \r
1615         CardDAVFooter.Data = this;\r
1616         CardDAVFooter.HeaderMode = FALSE;\r
1617 \r
1618         wxString Data1;\r
1619         wxString Data2;\r
1620         \r
1621         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
1622         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
1623         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
1624         \r
1625         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
1626         \r
1627         // Try SSL first.\r
1628 \r
1629 \r
1630         /*\r
1631         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
1632         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
1633         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
1634         \r
1635         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
1636         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
1637         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
1638 \r
1639         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
1640         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
1641         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
1642         \r
1643         */\r
1644 \r
1645         //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
1646 \r
1647         std::map<int,int>::iterator ActIter;\r
1648         struct UploadDataStruc UploadData;\r
1649         \r
1650         \r
1651         ActIter = ActivityListPtr->find((int)ItemIndex);\r
1652         \r
1653         static const char* query =\r
1654         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"\r
1655         "<C:addressbook-query xmlns:D=\"DAV:\""\r
1656         "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"\r
1657         "<D:prop><D:getetag/>"\r
1658         //"<C:address-data>"\r
1659         //"     <C:allprop/>"\r
1660         //"</C:address-data></D:prop>"\r
1661         "</D:prop>"\r
1662         "<C:filter/>"\r
1663         "</C:addressbook-query>";\r
1664 \r
1665         if (ServerSSL){\r
1666 \r
1667                 wxString ServerCertFilename;\r
1668                 bool MatchingCert = FALSE;\r
1669 \r
1670                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1671                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
1672                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1673                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1674                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1675                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1676                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1677                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1678                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1679                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1680                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
1681                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1682                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
1683                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1684 \r
1685                 //UploadData.readptr = &CardDAVDataQuery;\r
1686                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1687                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1688                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1689                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1690                 \r
1691                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
1692                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
1693                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
1694 \r
1695                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
1696 \r
1697                 if (wxFile::Exists(ServerCertFilename) == TRUE){\r
1698                 \r
1699                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
1700                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
1701                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
1702                 \r
1703                 }\r
1704 \r
1705                 claconncode = (curl_easy_perform(conn));\r
1706 \r
1707                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
1708                 // the local certificate in use.\r
1709 \r
1710                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
1711                         \r
1712                         curl_easy_cleanup(conn);\r
1713                         conn = curl_easy_init();\r
1714                         \r
1715                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1716                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
1717                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1718                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1719                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1720                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1721                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1722                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1723                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1724                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1725                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
1726                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1727                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
1728                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1729                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
1730                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));   \r
1731                         \r
1732                         claconncode = (curl_easy_perform(conn));\r
1733                         \r
1734                         // If claconncode is CURLE_OK then delete the certificate file as that\r
1735                         // is no longer needed.\r
1736                         \r
1737                         if (claconncode == CURLE_OK){\r
1738                         \r
1739                                 // Delete the certificate file.\r
1740                                 \r
1741                                 wxRemoveFile(ServerCertFilename);\r
1742                         \r
1743                         }\r
1744                 \r
1745                 }\r
1746 \r
1747                 // Check if it fails with a CURLE_SSL_CACERT then compare\r
1748                 // the certificates as PEM files.\r
1749                 \r
1750                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
1751                 \r
1752                         //curl_easy_cleanup(conn);\r
1753                         //conn = curl_easy_init();\r
1754 \r
1755                         CURL *sslerrconn;\r
1756                         sslerrconn = curl_easy_init();\r
1757                         CURLcode sslerrconncode;\r
1758 \r
1759                         //claconncode = (curl_easy_perform(conn));\r
1760 \r
1761                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
1762 \r
1763                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
1764                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
1765                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1766                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
1767                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
1768                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1769                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1770                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
1771                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
1772                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
1773                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1774                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
1775                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
1776                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
1777                 \r
1778                         wxString SSLLocalData;\r
1779                         wxString SSLServerData;\r
1780                 \r
1781                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
1782                 \r
1783                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
1784                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
1785                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
1786                         \r
1787                         wxFFile SSLLocalFile;\r
1788                         \r
1789 #if wxABI_VERSION < 20900\r
1790                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
1791 #else\r
1792                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
1793 #endif  \r
1794         \r
1795                         // Load the recovery database for tasks not done.\r
1796         \r
1797                         if (SSLLocalFile.IsOpened() == TRUE){\r
1798 \r
1799                         // Check if we are using wxWidgets version 2.8 or less and\r
1800                         // execute the required command accordingly.\r
1801         \r
1802                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
1803                 \r
1804         \r
1805                         }\r
1806                         \r
1807                         SSLServerData = SSLDataIter->second;\r
1808                         \r
1809                         if (SSLLocalData == SSLServerData){\r
1810                         \r
1811                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
1812                                 // and CURLOPT_SSL_VERIFYHOST off.\r
1813                         \r
1814                                 curl_easy_cleanup(conn);\r
1815                                 conn = curl_easy_init();\r
1816                                 \r
1817                                 PageData.clear();\r
1818                                 PageHeader.clear();\r
1819                         \r
1820                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
1821                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
1822                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1823                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1824                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1825                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1826                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1827                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1828                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1829                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1830                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
1831                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1832                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
1833                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1834                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
1835                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           \r
1836                         \r
1837                                 claconncode = (curl_easy_perform(conn));\r
1838                                 \r
1839                                 MatchingCert = TRUE;\r
1840                         \r
1841                         }\r
1842                         \r
1843                         if (MatchingCert == FALSE){\r
1844                 \r
1845                                 claconncode = CURLE_SSL_CACERT;\r
1846                                 return;\r
1847                 \r
1848                         }\r
1849                         \r
1850                         curl_easy_cleanup(sslerrconn);\r
1851                 \r
1852                 }\r
1853 \r
1854 \r
1855 \r
1856                 // Sort out SSL error.\r
1857                 \r
1858                 // When SSL cert error occurs, connect again and fetch certificates.\r
1859                 // Display a message to the user explaining that an invalid\r
1860                 // certificate has been given and let the user decide what\r
1861                 // to do next.\r
1862 \r
1863                 if (claconncode == CURLE_OK){\r
1864 \r
1865                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
1866                 \r
1867                         CURL *sslerrconn;\r
1868                         sslerrconn = curl_easy_init();\r
1869                         CURLcode sslerrconncode;\r
1870                 \r
1871                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
1872                 \r
1873                         // Replace conn with sslerrconn!\r
1874                 \r
1875                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
1876                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
1877                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1878                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
1879                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
1880                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1881                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1882                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
1883                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
1884                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
1885                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1886                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
1887                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
1888                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
1889                                         \r
1890                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
1891 \r
1892                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
1893                         SSLCertCol.SuccessCode = 1;\r
1894 \r
1895                         return;\r
1896                 \r
1897                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
1898                 \r
1899                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1900                                         curl_easy_strerror(claconncode));\r
1901                         int http_code = 0;\r
1902                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
1903                         fprintf(stderr, "Error code was: %d\n", http_code);\r
1904                                         \r
1905                         return;\r
1906                 \r
1907                 } else {\r
1908 \r
1909                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1910                                         curl_easy_strerror(claconncode));\r
1911                         int http_code = 0;\r
1912                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
1913                         fprintf(stderr, "Error code was: %d\n", http_code);\r
1914 \r
1915                         return;\r
1916 \r
1917                 }\r
1918 \r
1919         } else {\r
1920         \r
1921                 // No SSL.\r
1922         \r
1923                 wxString EmptyString;\r
1924                 \r
1925                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
1926                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
1927                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
1928                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
1929                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
1930                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
1931                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
1932                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
1933                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
1934                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
1935                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
1936                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
1937                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
1938                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
1939 \r
1940                 //UploadData.readptr = &CardDAVDataQuery;\r
1941                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
1942                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
1943                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
1944                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
1945                 \r
1946                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
1947                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
1948                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           \r
1949                 \r
1950                 PageData.Clear();\r
1951                 PageHeader.Clear();\r
1952                 \r
1953                 conncode = (curl_easy_perform(conn));\r
1954 \r
1955                 if (conncode == CURLE_OK){\r
1956 \r
1957                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
1958                 \r
1959                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1960                                         curl_easy_strerror(conncode));\r
1961                                         \r
1962                         return;\r
1963                 \r
1964                 } else {\r
1965 \r
1966                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
1967                                         curl_easy_strerror(conncode));\r
1968                                 \r
1969                         return;\r
1970 \r
1971                 }\r
1972                 \r
1973         }\r
1974         \r
1975         xmlDocPtr xmlCardDAVDoc;\r
1976 \r
1977         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
1978 \r
1979         xmlNodePtr nodeLevel1;\r
1980         xmlNodePtr nodeLevel2;\r
1981         xmlNodePtr nodeLevel3;\r
1982         xmlNodePtr nodeLevel4;\r
1983         xmlNodePtr nodeLevel5;\r
1984         xmlNodePtr nodeLevel6;\r
1985 \r
1986         std::map<wxString,wxString> xmlDataMap;\r
1987 \r
1988         wxString DataFilename;\r
1989         wxString ETagData;\r
1990 \r
1991         std::string xmlStringSafe;\r
1992 \r
1993         // Tranverse through the catacombs of the response to get our ETag for the file.\r
1994 \r
1995         for (nodeLevel1 = xmlCardDAVDoc->children;\r
1996                 nodeLevel1 != NULL;\r
1997                 nodeLevel1 = nodeLevel1->next)\r
1998         {\r
1999 \r
2000                 for (nodeLevel2 = nodeLevel1->children;\r
2001                         nodeLevel2 != NULL;\r
2002                         nodeLevel2 = nodeLevel2->next)\r
2003                 {\r
2004 \r
2005                         for (nodeLevel3 = nodeLevel2->children;\r
2006                         nodeLevel3 != NULL;\r
2007                         nodeLevel3 = nodeLevel3->next)\r
2008                         {\r
2009 \r
2010                                 bool HREFFound = FALSE;\r
2011                                 bool ETagFound = FALSE;\r
2012 \r
2013                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
2014                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
2015                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
2016                                 ){\r
2017 \r
2018                                         // Get the filename.\r
2019                                         \r
2020                                         for (nodeLevel4 = nodeLevel3->children;\r
2021                                         nodeLevel4 != NULL;\r
2022                                         nodeLevel4 = nodeLevel4->next)\r
2023                                         {\r
2024                                         \r
2025                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
2026                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
2027                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
2028                                                 ){\r
2029 \r
2030                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
2031                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
2032                                                 \r
2033                                                         while (wSTDFilename.HasMoreTokens()){\r
2034                                                         \r
2035                                                                 DataFilename = wSTDFilename.GetNextToken();\r
2036                                                         \r
2037                                                         }\r
2038                                                         \r
2039                                                         HREFFound = TRUE;\r
2040                                                 \r
2041                                                 }\r
2042                                                 \r
2043         \r
2044                                         \r
2045                                         }\r
2046 \r
2047                                 } else {\r
2048 \r
2049                                         for (nodeLevel4 = nodeLevel3->children;\r
2050                                         nodeLevel4 != NULL;\r
2051                                         nodeLevel4 = nodeLevel4->next)\r
2052                                         {\r
2053                                                         \r
2054                                                         for (nodeLevel5 = nodeLevel4->children;\r
2055                                                         nodeLevel5 != NULL;\r
2056                                                         nodeLevel5 = nodeLevel5->next)\r
2057                                                         {\r
2058 \r
2059                                                                 if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
2060                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
2061                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
2062                                                                 ){\r
2063 \r
2064                                                                         for (nodeLevel6 = nodeLevel5->children;\r
2065                                                                         nodeLevel6 != NULL;\r
2066                                                                         nodeLevel6 = nodeLevel6->next)\r
2067                                                                         {\r
2068                                                         \r
2069                                                                                 // Strip the quotes from the ETag.\r
2070                                                         \r
2071                                                                                 ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
2072                                                                                 if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
2073                                                         \r
2074                                                                                         ETagData.Remove(0, 1);\r
2075                                                                                         ETagData.RemoveLast();\r
2076                                                         \r
2077                                                                                 }\r
2078                                                                         \r
2079                                                                                 ETagFound = TRUE;\r
2080 \r
2081                                                                         }\r
2082                                                                         \r
2083                                                                 }\r
2084 \r
2085                                                         }       \r
2086 \r
2087                                         }\r
2088 \r
2089                                 }\r
2090 \r
2091                                 if (HREFFound == TRUE && ETagFound == TRUE){\r
2092                                 \r
2093                                         // Add to the map data.\r
2094                                         \r
2095                                         xmlDataMap.insert(std::make_pair(DataFilename, ETagData));\r
2096                                 \r
2097                                 }\r
2098                                 \r
2099                                 // Reset the values.\r
2100                                 \r
2101                                 HREFFound = FALSE;\r
2102                                 ETagFound = FALSE;\r
2103 \r
2104                         }\r
2105 \r
2106                 }\r
2107 \r
2108 \r
2109         }\r
2110 \r
2111         xmlFreeDoc(xmlCardDAVDoc);\r
2112 \r
2113         // Get the first result.\r
2114 \r
2115         for (std::map<wxString,wxString>::iterator iter = xmlDataMap.begin(); \r
2116                 iter != xmlDataMap.end(); ++iter){\r
2117         \r
2118                 ETagResult = iter->second;\r
2119                 break;\r
2120                 \r
2121         }\r
2122         \r
2123         if (ETagResult.IsEmpty()){\r
2124         \r
2125                 return;\r
2126         \r
2127         }\r
2128         \r
2129         return;\r
2130         \r
2131 }\r
2132 \r
2133 wxString CardDAV::ETagValueResult(){\r
2134 \r
2135         return ETagResult;\r
2136 \r
2137 }\r
2138 \r
2139 void CardDAV::GetServerETagValue(){\r
2140 \r
2141         std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this);\r
2142         ConnectThread.detach();\r
2143 \r
2144 }\r
2145 \r
2146 void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){\r
2147 \r
2148         ServerMethod = Method;\r
2149         ServerFilenameLocation = FilenameLocation;\r
2150         ServerUploadData = UploadData;\r
2151 \r
2152         // Check if ServerFilenameLocation has a / at \r
2153         // the start and if not then append it.\r
2154         \r
2155         if (ServerFilenameLocation.Left(1) != wxT("/")){\r
2156         \r
2157                 // Not there so insert.\r
2158                 \r
2159                 ServerFilenameLocation = wxT("/") + ServerFilenameLocation;\r
2160         \r
2161         }\r
2162 \r
2163 }\r
2164 \r
2165 void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){\r
2166 \r
2167         ActivityListPtr = actlist;\r
2168         ItemIndex = actindex;\r
2169 \r
2170 }\r
2171 \r
2172 wxString CardDAV::GetETagData(){\r
2173 \r
2174         return ETagData;\r
2175 \r
2176 }\r
2177 \r
2178 void CardDAV::SetUploadMode(bool IncMode){\r
2179 \r
2180         UploadMode = IncMode;\r
2181 \r
2182 }\r
2183 \r
2184 void CardDAV::SetEditMode(bool EditModeInc){\r
2185 \r
2186         EditMode = EditModeInc;\r
2187 \r
2188 }\r
2189 \r
2190 ContactListData CardDAV::GetContactList(wxString SyncTokenInc){\r
2191 \r
2192         ContactListData ContactListFinal;\r
2193         std::map<wxString,FileSyncData> ContactList;\r
2194         \r
2195         PageData.Clear();\r
2196         PageHeader.Clear();\r
2197 \r
2198         SSLStatus = TRUE;\r
2199         AuthPassed = TRUE;\r
2200         AbortConnection = FALSE;\r
2201 \r
2202         CURL *conn;\r
2203         wxString ServerAddressURL;\r
2204         wxString ServerAuth;\r
2205         wxString ServerAddressSSL;\r
2206         wxString ServerAddressNormal;\r
2207 \r
2208         conn = curl_easy_init();\r
2209         \r
2210         struct CardDAVCURLPasser {\r
2211         \r
2212                 CardDAV *Data;\r
2213                 bool HeaderMode = TRUE;\r
2214         \r
2215         } CardDAVHeader, CardDAVFooter;\r
2216 \r
2217         CardDAVHeader.Data = this;\r
2218         CardDAVHeader.HeaderMode = TRUE;\r
2219         \r
2220         CardDAVFooter.Data = this;\r
2221         CardDAVFooter.HeaderMode = FALSE;\r
2222 \r
2223         wxString Data1;\r
2224         wxString Data2;\r
2225         \r
2226         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/");\r
2227         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
2228         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
2229         \r
2230         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
2231         \r
2232         // Load the sync token file (if it exists).\r
2233         \r
2234         wxCharBuffer SyncDataBuffer;\r
2235         wxString SyncData;\r
2236         \r
2237         SyncData.Clear();\r
2238         \r
2239         SyncTokenInc.Trim();\r
2240         \r
2241         if (!SyncTokenInc.IsEmpty()){\r
2242                 \r
2243                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");\r
2244                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));\r
2245                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));\r
2246                 SyncData.Append(wxT("<D:sync-token>"));\r
2247                 //SyncData.Trim();\r
2248                 //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580"));\r
2249                 SyncData.Append(SyncTokenInc);\r
2250                 //SyncData.Trim();\r
2251                 SyncData.Append(wxT("</D:sync-token>\n"));\r
2252                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));\r
2253                 SyncData.Append(wxT("<D:prop>\n"));\r
2254                 SyncData.Append(wxT("   <D:getetag/>\n"));\r
2255                 SyncData.Append(wxT("</D:prop>\n"));\r
2256                 SyncData.Append(wxT("</D:sync-collection>"));\r
2257                 \r
2258                 SyncDataBuffer = SyncData.ToUTF8();\r
2259         \r
2260         } else {\r
2261                 \r
2262                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
2263                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));\r
2264                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));\r
2265                 SyncData.Append(wxT("<D:sync-token/>\n"));\r
2266                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));\r
2267                 SyncData.Append(wxT("<D:prop>\n"));\r
2268                 SyncData.Append(wxT("   <D:getetag/>\n"));\r
2269                 SyncData.Append(wxT("</D:prop>\n"));\r
2270                 SyncData.Append(wxT("</D:sync-collection>\n"));\r
2271                 \r
2272                 SyncDataBuffer = SyncData.ToUTF8();\r
2273 \r
2274         }\r
2275         \r
2276         //static const char* query = SyncData.mb_str();\r
2277         \r
2278         /*char *query = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\\r
2279                 <D:sync-collection xmlns:D=\"DAV:\"\n\\r
2280                  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n\\r
2281                 <D:sync-token>data:,00378c55-1f44-44a2-a255-84f6560b5cac_580</D:sync-token>\n\\r
2282                 <D:sync-level>1</D:sync-level>\n\\r
2283                 <D:prop>\n\\r
2284                         <D:getetag/>\n\\r
2285                 </D:prop>\n\\r
2286         </D:sync-collection>\n";*/\r
2287         const char* query = SyncDataBuffer.data();\r
2288         \r
2289         // Try SSL first.\r
2290 \r
2291         std::map<int,int>::iterator ActIter;\r
2292         struct UploadDataStruc UploadData;\r
2293         \r
2294         ActIter = ActivityListPtr->find((int)ItemIndex);\r
2295 \r
2296         curl_slist *slist = NULL;       \r
2297 \r
2298         slist = curl_slist_append(slist, "Depth: 1");\r
2299 \r
2300         if (ServerSSL){\r
2301 \r
2302                 wxString ServerCertFilename;\r
2303                 bool MatchingCert = FALSE;\r
2304 \r
2305                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
2306                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
2307                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
2308                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
2309                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
2310                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2311                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
2312                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2313                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
2314                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
2315                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
2316                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2317                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
2318                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
2319                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
2320                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
2321 \r
2322                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
2323 \r
2324                 if (wxFile::Exists(ServerCertFilename) == TRUE){\r
2325                 \r
2326                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
2327                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
2328                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
2329                 \r
2330                 }\r
2331 \r
2332                 //UploadData.readptr = &CardDAVDataQuery;\r
2333                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
2334                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
2335                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
2336                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
2337                 \r
2338                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
2339                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
2340                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
2341 \r
2342                 claconncode = (curl_easy_perform(conn));\r
2343 \r
2344                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
2345                 // the local certificate in use.\r
2346 \r
2347                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
2348                         \r
2349                         curl_easy_cleanup(conn);\r
2350                         conn = curl_easy_init();\r
2351                         \r
2352                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
2353                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
2354                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
2355                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
2356                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
2357                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2358                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
2359                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2360                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
2361                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
2362                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
2363                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2364                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
2365                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
2366                         curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
2367                         curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
2368                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
2369                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
2370                         \r
2371                         claconncode = (curl_easy_perform(conn));\r
2372                         \r
2373                         // If claconncode is CURLE_OK then delete the certificate file as that\r
2374                         // is no longer needed.\r
2375                         \r
2376                         if (claconncode == CURLE_OK){\r
2377                         \r
2378                                 // Delete the certificate file.\r
2379                                 \r
2380                                 wxRemoveFile(ServerCertFilename);\r
2381                         \r
2382                         }\r
2383                 \r
2384                 }\r
2385 \r
2386                 // Check if it fails with a CURLE_SSL_CACERT then compare\r
2387                 // the certificates as PEM files.\r
2388                 \r
2389                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
2390                 \r
2391                         //curl_easy_cleanup(conn);\r
2392                         //conn = curl_easy_init();\r
2393 \r
2394                         CURL *sslerrconn;\r
2395                         sslerrconn = curl_easy_init();\r
2396                         CURLcode sslerrconncode;\r
2397 \r
2398                         //claconncode = (curl_easy_perform(conn));\r
2399 \r
2400                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
2401 \r
2402                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
2403                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
2404                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
2405                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
2406                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
2407                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2408                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2409                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
2410                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
2411                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
2412                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2413                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
2414                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
2415                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
2416                 \r
2417                         wxString SSLLocalData;\r
2418                         wxString SSLServerData;\r
2419                 \r
2420                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
2421                 \r
2422                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
2423                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
2424                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
2425                         \r
2426                         wxFFile SSLLocalFile;\r
2427                         \r
2428 #if wxABI_VERSION < 20900\r
2429                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
2430 #else\r
2431                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
2432 #endif  \r
2433         \r
2434                         // Load the recovery database for tasks not done.\r
2435         \r
2436                         if (SSLLocalFile.IsOpened() == TRUE){\r
2437 \r
2438                         // Check if we are using wxWidgets version 2.8 or less and\r
2439                         // execute the required command accordingly.\r
2440         \r
2441                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
2442                 \r
2443         \r
2444                         }\r
2445                         \r
2446                         SSLServerData = SSLDataIter->second;\r
2447                         \r
2448                         if (SSLLocalData == SSLServerData){\r
2449                         \r
2450                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
2451                                 // and CURLOPT_SSL_VERIFYHOST off.\r
2452                         \r
2453                                 curl_easy_cleanup(conn);\r
2454                                 conn = curl_easy_init();\r
2455                                 \r
2456                                 PageHeader.clear();\r
2457                                 PageData.clear();\r
2458                                 \r
2459                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
2460                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
2461                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
2462                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
2463                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
2464                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2465                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
2466                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2467                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
2468                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
2469                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
2470                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2471                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
2472                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
2473                                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
2474                                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
2475                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
2476                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
2477                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
2478                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
2479                         \r
2480                                 claconncode = (curl_easy_perform(conn));\r
2481                                 \r
2482                                 MatchingCert = TRUE;\r
2483                         \r
2484                         }\r
2485                         \r
2486                         if (MatchingCert == FALSE){\r
2487                 \r
2488                                 claconncode = CURLE_SSL_CACERT;\r
2489                                 return ContactListFinal;\r
2490                 \r
2491                         }\r
2492                         \r
2493                         curl_easy_cleanup(sslerrconn);\r
2494                 \r
2495                 }\r
2496 \r
2497                 // Sort out SSL error.\r
2498                 \r
2499                 // When SSL cert error occurs, connect again and fetch certificates.\r
2500                 // Display a message to the user explaining that an invalid\r
2501                 // certificate has been given and let the user decide what\r
2502                 // to do next.\r
2503 \r
2504                 if (claconncode == CURLE_OK){\r
2505 \r
2506                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
2507                 \r
2508                         CURL *sslerrconn;\r
2509                         sslerrconn = curl_easy_init();\r
2510                         CURLcode sslerrconncode;\r
2511                 \r
2512                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
2513                 \r
2514                         // Replace conn with sslerrconn!\r
2515                 \r
2516                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
2517                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
2518                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
2519                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
2520                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
2521                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2522                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2523                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
2524                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
2525                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
2526                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2527                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
2528                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
2529                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
2530                 \r
2531                         sslerrconncode = (curl_easy_perform(sslerrconn));\r
2532 \r
2533                         SSLCertCol = BuildSSLCollection(sslerrconn);\r
2534                         SSLCertCol.SuccessCode = 1;\r
2535 \r
2536                         return ContactListFinal;\r
2537                 \r
2538                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
2539                 \r
2540                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
2541                                         curl_easy_strerror(claconncode));\r
2542                         int http_code = 0;\r
2543                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
2544                         fprintf(stderr, "Error code was: %d\n", http_code);\r
2545                                         \r
2546                         return ContactListFinal;\r
2547                 \r
2548                 } else {\r
2549 \r
2550                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
2551                                         curl_easy_strerror(claconncode));\r
2552                         int http_code = 0;\r
2553                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
2554                         fprintf(stderr, "Error code was: %d\n", http_code);\r
2555 \r
2556                         return ContactListFinal;\r
2557 \r
2558                 }\r
2559 \r
2560                 SSLCertCol = BuildSSLCollection(conn);\r
2561 \r
2562         } else {\r
2563         \r
2564         // No SSL.\r
2565                 \r
2566                 wxString EmptyString;\r
2567                 \r
2568                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
2569                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
2570                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
2571                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
2572                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
2573                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
2574                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
2575                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
2576                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
2577                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
2578                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
2579                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
2580                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
2581                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
2582                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
2583 \r
2584                 //UploadData.readptr = &CardDAVDataQuery;\r
2585                 //UploadData.sizeleft = CardDAVDataQuery.Len();\r
2586                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
2587                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
2588                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
2589                 \r
2590                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
2591                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
2592                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           \r
2593                 \r
2594                 PageData.Clear();\r
2595                 PageHeader.Clear();\r
2596                 \r
2597                 claconncode = (curl_easy_perform(conn));\r
2598 \r
2599                 if (claconncode == CURLE_OK){\r
2600 \r
2601 \r
2602 \r
2603                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
2604                 \r
2605                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
2606                                         curl_easy_strerror(claconncode));\r
2607                         int http_code = 0;\r
2608                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
2609                         fprintf(stderr, "Error code was: %i\n", http_code);\r
2610                                         \r
2611                         return ContactListFinal;\r
2612                         \r
2613                 } else {\r
2614 \r
2615                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
2616                                         curl_easy_strerror(claconncode));\r
2617                         int http_code = 0;\r
2618                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
2619                         fprintf(stderr, "Error code was: %i\n", http_code);\r
2620                                 \r
2621                         return ContactListFinal;\r
2622 \r
2623                 }\r
2624                 \r
2625         }\r
2626 \r
2627         xmlDocPtr xmlCardDAVDoc;\r
2628         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
2629 \r
2630         xmlNodePtr nodeLevel1;\r
2631         xmlNodePtr nodeLevel2;\r
2632         xmlNodePtr nodeLevel3;\r
2633         xmlNodePtr nodeLevel4;\r
2634         xmlNodePtr nodeLevel5;\r
2635         xmlNodePtr nodeLevel6;\r
2636         \r
2637         xmlNodePtr nodeStatusLv1;\r
2638         xmlNodePtr nodeStatusLv2;\r
2639 \r
2640         std::map<wxString,wxString> xmlDataMap;\r
2641         std::map<wxString,wxString> ServerETagData;\r
2642 \r
2643         wxString DataFilename;\r
2644         wxString DataSyncToken;\r
2645         int DataFileStatus;\r
2646         wxString ETagData;\r
2647         bool SyncTokenFound = FALSE;\r
2648 \r
2649         std::string xmlStringSafe;\r
2650 \r
2651         // Tranverse through the catacombs of the response to get our ETag for the file and\r
2652         // the server syncronisation token.\r
2653 \r
2654         // Start by getting all the server ETag data.\r
2655 \r
2656         for (nodeLevel1 = xmlCardDAVDoc->children;\r
2657                 nodeLevel1 != NULL;\r
2658                 nodeLevel1 = nodeLevel1->next)\r
2659         {\r
2660 \r
2661                 for (nodeLevel2 = nodeLevel1->children;\r
2662                         nodeLevel2 != NULL;\r
2663                         nodeLevel2 = nodeLevel2->next)\r
2664                 {\r
2665 \r
2666                         printf("\t%s:%s\n", nodeLevel2->name, nodeLevel2->content);\r
2667 \r
2668                         for (nodeLevel3 = nodeLevel2->children;\r
2669                         nodeLevel3 != NULL;\r
2670                         nodeLevel3 = nodeLevel3->next)\r
2671                         {\r
2672 \r
2673                                 DataFileStatus = 0;\r
2674                                 bool HREFFound = FALSE;\r
2675                                 bool ETagFound = FALSE;\r
2676                                 bool HTTPStatus = FALSE;\r
2677 \r
2678                                 printf("\t\t%s:%s\n", nodeLevel3->name, nodeLevel3->content);\r
2679 \r
2680                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
2681                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
2682                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
2683                                 ){\r
2684 \r
2685                                         // Get the filename.\r
2686                                         \r
2687                                         for (nodeLevel4 = nodeLevel3->children;\r
2688                                         nodeLevel4 != NULL;\r
2689                                         nodeLevel4 = nodeLevel4->next)\r
2690                                         {\r
2691                                         \r
2692                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
2693                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
2694                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
2695                                                 ){\r
2696                                                 \r
2697                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
2698                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
2699                                                 \r
2700                                                         while (wSTDFilename.HasMoreTokens()){\r
2701                                                         \r
2702                                                                 DataFilename = wSTDFilename.GetNextToken();\r
2703                                                         \r
2704                                                         }\r
2705                                                         \r
2706                                                         HREFFound = TRUE;\r
2707                                                 \r
2708                                                 }\r
2709                                                 \r
2710         \r
2711                                         \r
2712                                         }\r
2713                                         \r
2714 \r
2715                                 } else {\r
2716 \r
2717                                         for (nodeLevel4 = nodeLevel3->children;\r
2718                                         nodeLevel4 != NULL;\r
2719                                         nodeLevel4 = nodeLevel4->next)\r
2720                                         {\r
2721 \r
2722                                                 for (nodeStatusLv1 = nodeLevel3->children;\r
2723                                                         nodeStatusLv1 != NULL;\r
2724                                                         nodeStatusLv1 = nodeStatusLv1->next)\r
2725                                                 {\r
2726 \r
2727                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){\r
2728                 \r
2729                                                                 DataFileStatus = 2;\r
2730                                                                                 \r
2731                                                                 HTTPStatus = TRUE;\r
2732                                                                                 \r
2733                                                         }\r
2734                                         \r
2735                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||\r
2736                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||\r
2737                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)\r
2738                                                         {\r
2739 \r
2740                                                                 // Get the filename.\r
2741                                         \r
2742                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;\r
2743                                                                 nodeStatusLv2 != NULL;\r
2744                                                                 nodeStatusLv2 = nodeStatusLv2->next)\r
2745                                                                 {\r
2746                                         \r
2747                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||\r
2748                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||\r
2749                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")\r
2750                                                                         ){\r
2751 \r
2752                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){\r
2753                                                                         \r
2754                                                                                         DataFileStatus = 1;\r
2755                                                                                         \r
2756                                                                                         HTTPStatus = TRUE;\r
2757                                                                         \r
2758                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.\r
2759                                                                         \r
2760                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){\r
2761                                                                                 \r
2762                                                                                 //      DataFileStatus = 0;\r
2763                                                                                 \r
2764                                                                                 }\r
2765                                                 \r
2766                                                                         }\r
2767                                                 \r
2768         \r
2769                                         \r
2770                                                                 }\r
2771                                                         \r
2772                                                         }\r
2773 \r
2774                                         \r
2775                                                 }\r
2776                                                 \r
2777                                                 for (nodeLevel5 = nodeLevel4->children;\r
2778                                                 nodeLevel5 != NULL;\r
2779                                                 nodeLevel5 = nodeLevel5->next)\r
2780                                                 {\r
2781 \r
2782                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
2783                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
2784                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
2785                                                         ){\r
2786 \r
2787                                                                 for (nodeLevel6 = nodeLevel5->children;\r
2788                                                                 nodeLevel6 != NULL;\r
2789                                                                 nodeLevel6 = nodeLevel6->next)\r
2790                                                                 {\r
2791 \r
2792                                                                         // Strip the quotes from the ETag.\r
2793                                                 \r
2794                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
2795                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
2796                                                 \r
2797                                                                                 ETagData.Remove(0, 1);\r
2798                                                                                 ETagData.RemoveLast();\r
2799                                                 \r
2800                                                                         }\r
2801                                                                 \r
2802                                                                         ETagFound = TRUE;\r
2803 \r
2804                                                                 }\r
2805                                                                 \r
2806                                                         }\r
2807 \r
2808                                                 }       \r
2809 \r
2810                                         }\r
2811 \r
2812                                 }\r
2813 \r
2814                                 if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){\r
2815                                 \r
2816                                         // Add to the map data.\r
2817                                         \r
2818                                         FileSyncData SData;\r
2819                                         \r
2820                                         SData.ETagData = ETagData;\r
2821                                         SData.DataFlag = DataFileStatus;\r
2822                                         \r
2823                                         ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));\r
2824                                 \r
2825                                 }\r
2826                                 \r
2827                                 // Reset the values.\r
2828                                 \r
2829                                 HREFFound = FALSE;\r
2830                                 ETagFound = FALSE;\r
2831                                 HTTPStatus = FALSE;\r
2832 \r
2833                         }\r
2834 \r
2835                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||\r
2836                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||\r
2837                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&\r
2838                         SyncTokenFound == FALSE\r
2839                         ){\r
2840 \r
2841                                 for (nodeLevel3 = nodeLevel2->children;\r
2842                                 nodeLevel3 != NULL;\r
2843                                 nodeLevel3 = nodeLevel3->next)\r
2844                                 {\r
2845 \r
2846                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||\r
2847                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||\r
2848                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")\r
2849                                         ){\r
2850                         \r
2851                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);\r
2852 \r
2853                                                 SyncTokenFound = TRUE;\r
2854                         \r
2855                                         }\r
2856                         \r
2857                                 }\r
2858         \r
2859                         }\r
2860 \r
2861                 }\r
2862 \r
2863         }\r
2864         \r
2865         for (nodeLevel1 = xmlCardDAVDoc->children;\r
2866                 nodeLevel1 != NULL;\r
2867                 nodeLevel1 = nodeLevel1->next)\r
2868         {\r
2869 \r
2870                 for (nodeLevel2 = nodeLevel1->children;\r
2871                         nodeLevel2 != NULL;\r
2872                         nodeLevel2 = nodeLevel2->next)\r
2873                 {\r
2874 \r
2875                         printf("\t%s:%s\n", nodeLevel2->name, nodeLevel2->content);\r
2876 \r
2877                         DataFileStatus = 0;\r
2878                         bool HREFFound = FALSE;\r
2879                         bool ETagFound = FALSE;\r
2880                         bool HTTPStatus = FALSE;\r
2881 \r
2882                         for (nodeLevel3 = nodeLevel2->children;\r
2883                         nodeLevel3 != NULL;\r
2884                         nodeLevel3 = nodeLevel3->next)\r
2885                         {\r
2886 \r
2887                                 printf("\t\t%s:%s\n", nodeLevel3->name, nodeLevel3->content);\r
2888 \r
2889                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
2890                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
2891                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
2892                                 ){\r
2893 \r
2894                                         // Get the filename.\r
2895                                         \r
2896                                         for (nodeLevel4 = nodeLevel3->children;\r
2897                                         nodeLevel4 != NULL;\r
2898                                         nodeLevel4 = nodeLevel4->next)\r
2899                                         {\r
2900                                         \r
2901                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
2902                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
2903                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
2904                                                 ){\r
2905                                                 \r
2906                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
2907                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
2908                                                 \r
2909                                                         while (wSTDFilename.HasMoreTokens()){\r
2910                                                         \r
2911                                                                 DataFilename = wSTDFilename.GetNextToken();\r
2912                                                         \r
2913                                                         }\r
2914                                                         \r
2915                                                         HREFFound = TRUE;\r
2916                                                 \r
2917                                                 }\r
2918                                                 \r
2919         \r
2920                                         \r
2921                                         }\r
2922                                         \r
2923 \r
2924                                 } else {\r
2925 \r
2926                                         for (nodeLevel4 = nodeLevel3->children;\r
2927                                         nodeLevel4 != NULL;\r
2928                                         nodeLevel4 = nodeLevel4->next)\r
2929                                         {\r
2930 \r
2931                                                 for (nodeStatusLv1 = nodeLevel3->children;\r
2932                                                         nodeStatusLv1 != NULL;\r
2933                                                         nodeStatusLv1 = nodeStatusLv1->next)\r
2934                                                 {\r
2935 \r
2936                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){\r
2937                 \r
2938                                                                 DataFileStatus = 2;\r
2939 \r
2940                                                                 HTTPStatus = TRUE;\r
2941                                                                                 \r
2942                                                         }\r
2943                                         \r
2944                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||\r
2945                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||\r
2946                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)\r
2947                                                         {\r
2948 \r
2949                                                                 // Get the filename.\r
2950                                         \r
2951                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;\r
2952                                                                 nodeStatusLv2 != NULL;\r
2953                                                                 nodeStatusLv2 = nodeStatusLv2->next)\r
2954                                                                 {\r
2955                                         \r
2956                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||\r
2957                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||\r
2958                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")\r
2959                                                                         ){\r
2960 \r
2961                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){\r
2962 \r
2963                                                                                         DataFileStatus = 1;\r
2964                                                                                         \r
2965                                                                                         HTTPStatus = TRUE;\r
2966                                                                         \r
2967                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.\r
2968                                                                         \r
2969                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){\r
2970                                                                                 \r
2971                                                                                 //      DataFileStatus = 0;\r
2972                                                                                 \r
2973                                                                                 }\r
2974                                                 \r
2975                                                                         }\r
2976                                                 \r
2977         \r
2978                                         \r
2979                                                                 }\r
2980                                                         \r
2981                                                         }\r
2982 \r
2983                                         \r
2984                                                 }\r
2985                                                 \r
2986                                                 for (nodeLevel5 = nodeLevel4->children;\r
2987                                                 nodeLevel5 != NULL;\r
2988                                                 nodeLevel5 = nodeLevel5->next)\r
2989                                                 {\r
2990 \r
2991                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
2992                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
2993                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
2994                                                         ){\r
2995 \r
2996                                                                 for (nodeLevel6 = nodeLevel5->children;\r
2997                                                                 nodeLevel6 != NULL;\r
2998                                                                 nodeLevel6 = nodeLevel6->next)\r
2999                                                                 {\r
3000 \r
3001                                                                         // Strip the quotes from the ETag.\r
3002                                                 \r
3003                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
3004                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
3005                                                 \r
3006                                                                                 ETagData.Remove(0, 1);\r
3007                                                                                 ETagData.RemoveLast();\r
3008                                                 \r
3009                                                                         }\r
3010                                                                 \r
3011                                                                         ETagFound = TRUE;\r
3012 \r
3013                                                                 }\r
3014                                                                 \r
3015                                                         }\r
3016 \r
3017                                                 }       \r
3018 \r
3019                                         }\r
3020 \r
3021                                 }\r
3022 \r
3023                         }\r
3024 \r
3025                         if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){\r
3026                         \r
3027                                 FileSyncData SData;\r
3028                                         \r
3029                                 SData.ETagData = wxT("");\r
3030                                 SData.DataFlag = DataFileStatus;\r
3031                                         \r
3032                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          \r
3033                         \r
3034                         }\r
3035 \r
3036                         if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){\r
3037                                 \r
3038                                 // Add to the map data.\r
3039                                         \r
3040                                 FileSyncData SData;\r
3041                                         \r
3042                                 SData.ETagData = ETagData;\r
3043                                 SData.DataFlag = DataFileStatus;\r
3044                                         \r
3045                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));\r
3046                                 \r
3047                         }\r
3048                                 \r
3049                         // Reset the values.\r
3050                                 \r
3051                         HREFFound = FALSE;\r
3052                         ETagFound = FALSE;\r
3053                         HTTPStatus = FALSE;\r
3054                         DataFilename.Clear();\r
3055 \r
3056                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||\r
3057                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||\r
3058                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&\r
3059                         SyncTokenFound == FALSE\r
3060                         ){\r
3061 \r
3062                                 for (nodeLevel3 = nodeLevel2->children;\r
3063                                 nodeLevel3 != NULL;\r
3064                                 nodeLevel3 = nodeLevel3->next)\r
3065                                 {\r
3066 \r
3067                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||\r
3068                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||\r
3069                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")\r
3070                                         ){\r
3071                         \r
3072                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);\r
3073 \r
3074                                                 SyncTokenFound = TRUE;\r
3075                         \r
3076                                         }\r
3077                         \r
3078                                 }\r
3079         \r
3080                         }\r
3081 \r
3082                 }\r
3083 \r
3084         }\r
3085         \r
3086         // Get the sync token.\r
3087         \r
3088         if (SyncTokenFound == TRUE){\r
3089         \r
3090                 ContactListFinal.SyncToken = DataSyncToken;\r
3091         \r
3092         } else {\r
3093         \r
3094         }\r
3095 \r
3096         SleepFor(2000000000);\r
3097 \r
3098         /*timespec n1, n2;\r
3099                                                 \r
3100         n1.tv_sec = 0;\r
3101         n1.tv_nsec = 2000000000L;\r
3102                 \r
3103         nanosleep(&n1, &n2);*/\r
3104 \r
3105         xmlFreeDoc(xmlCardDAVDoc);\r
3106         curl_easy_cleanup(conn);\r
3107 \r
3108         SyncDataBuffer.reset();\r
3109 \r
3110         // Get the first result.\r
3111 \r
3112         return ContactListFinal;\r
3113 \r
3114 }\r
3115 \r
3116 int CardDAV::GetResultCode(){\r
3117 \r
3118         return (int)claconncode;\r
3119 \r
3120 }\r
3121 \r
3122 int CardDAV::GetHTTPCode(){\r
3123 \r
3124         return HTTPErrorCode;\r
3125 \r
3126 }\r
3127 \r
3128 wxString CardDAV::GetErrorBuffer(){\r
3129 \r
3130         wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);\r
3131 \r
3132         return ErrorBuffer;\r
3133 \r
3134 }\r
3135 \r
3136 wxString CardDAV::GetDefaultAddressBookURL(){\r
3137 \r
3138         // First: Get the principal UID address.\r
3139         \r
3140         PageData.Clear();\r
3141         PageHeader.Clear();\r
3142 \r
3143         SSLStatus = TRUE;\r
3144         AuthPassed = TRUE;\r
3145         AbortConnection = FALSE;\r
3146 \r
3147     CURL *conn;\r
3148     CURLcode conncode;\r
3149         wxString ServerAddressURL;\r
3150         wxString ServerAuth;\r
3151         wxString ServerAddressSSL;\r
3152         wxString ServerAddressNormal;   \r
3153 \r
3154         conn = curl_easy_init();\r
3155         \r
3156         struct curl_slist *connhd = NULL;\r
3157         struct curl_slist *connhd2 = NULL;\r
3158         struct curl_slist *connhd3 = NULL;\r
3159 \r
3160         connhd = curl_slist_append(connhd, "Depth: 0");\r
3161         connhd = curl_slist_append(connhd, "Prefer: return-minimal");\r
3162         connhd = curl_slist_append(connhd, "Content-Type: application/xml; charset=utf-8");\r
3163 \r
3164         connhd2 = curl_slist_append(connhd2, "Depth: 0");\r
3165         connhd2 = curl_slist_append(connhd2, "Prefer: return-minimal");\r
3166         connhd2 = curl_slist_append(connhd2, "Content-Type: application/xml; charset=utf-8");\r
3167 \r
3168         connhd3 = curl_slist_append(connhd3, "Depth: 1");\r
3169         connhd3 = curl_slist_append(connhd3, "Prefer: return-minimal");\r
3170         connhd3 = curl_slist_append(connhd3, "Content-Type: application/xml; charset=utf-8");\r
3171 \r
3172         struct CardDAVCURLPasser {\r
3173         \r
3174                 CardDAV *Data;\r
3175                 bool HeaderMode = TRUE;\r
3176         \r
3177         } CardDAVHeader, CardDAVFooter;\r
3178 \r
3179         CardDAVHeader.Data = this;\r
3180         CardDAVHeader.HeaderMode = TRUE;\r
3181         \r
3182         CardDAVFooter.Data = this;\r
3183         CardDAVFooter.HeaderMode = FALSE;\r
3184 \r
3185         wxString Data1;\r
3186         wxString Data2;\r
3187         \r
3188         wxString ETag;\r
3189         wxString ETagOriginal;\r
3190         wxString ETagServer;\r
3191         \r
3192         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
3193         ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
3194         ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
3195         \r
3196         ServerAuth = ServerUser + wxT(":") + ServerPass;\r
3197         \r
3198         wxString SAURLPrincipals = ServerAddressURL + wxT("principals/");\r
3199         wxString SAURLPrincipalURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort);\r
3200         wxString SAURLAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort);\r
3201         wxString FinalPrefix;\r
3202 \r
3203         struct UploadDataStruc UploadData;\r
3204         \r
3205         // Setup the first query finding out where the principal URL is.\r
3206         \r
3207         const char* query = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
3208                 "<D:propfind xmlns:D=\"DAV:\">\n"\r
3209                 " <D:prop>"\r
3210                 "  <D:current-user-principal/>\n"\r
3211                 " </D:prop>"\r
3212                 "</D:propfind>";\r
3213 \r
3214         // Setup the second query finding out where the address book home URL is.\r
3215         \r
3216         const char* query2 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
3217         "<D:propfind xmlns:D=\"DAV:\""\r
3218         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"\r
3219         "  <D:prop>\n"\r
3220         "    <C:addressbook-home-set/>\n"\r
3221         "  </D:prop>\n"\r
3222         "</D:propfind>";\r
3223         \r
3224         // Setup the third query finding out where the default address book URL is.\r
3225         \r
3226         const char* query3 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
3227         "<D:propfind xmlns:D=\"DAV:\""\r
3228         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"\r
3229         "  <D:prop>\n"\r
3230         "    <C:default-addressbook-URL/>\n"    \r
3231         "  </D:prop>\n"\r
3232         "</D:propfind>";\r
3233         \r
3234         if (ServerSSL){\r
3235 \r
3236                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));\r
3237                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
3238                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
3239                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3240                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
3241                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
3242                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3243                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3244                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3245                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3246                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3247 \r
3248                 if (UploadMode == TRUE){\r
3249 \r
3250                         UploadData.readptr = &ServerUploadData;\r
3251                         UploadData.sizeleft = ServerUploadData.Len();\r
3252                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
3253                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
3254                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
3255                 \r
3256                 }\r
3257 \r
3258                 conncode = (curl_easy_perform(conn));\r
3259 \r
3260                 if (conncode == CURLE_OK){\r
3261 \r
3262                         *ServerResult = TRUE;\r
3263                         AuthPassed = TRUE;\r
3264                         SSLStatus = TRUE;\r
3265                         return wxT("");\r
3266 \r
3267                 } else {\r
3268 \r
3269                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3270                                         curl_easy_strerror(conncode));                                  \r
3271                                         \r
3272                         *ServerResult = FALSE;\r
3273                         \r
3274                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3275                         \r
3276                         return wxT("");                                 \r
3277 \r
3278                 }\r
3279 \r
3280         } else {\r
3281         \r
3282                 // No SSL.\r
3283 \r
3284                 // Do an initial connection (incase of Digest authentication).\r
3285 \r
3286                 PageData.Clear();\r
3287                 PageHeader.Clear();\r
3288 \r
3289                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));\r
3290                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
3291                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
3292                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3293                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
3294                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
3295                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3296                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3297                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3298                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3299                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
3300                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
3301                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3302                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
3303                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
3304                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
3305                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd);\r
3306                 \r
3307                 conncode = (curl_easy_perform(conn));\r
3308 \r
3309                 // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
3310                 // then bring up the conflict resolution form.\r
3311                 \r
3312                 if (EditMode == TRUE){\r
3313                 \r
3314                 }\r
3315 \r
3316                 if (conncode == CURLE_OK){\r
3317 \r
3318                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
3319 \r
3320                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3321                 \r
3322                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3323                                         curl_easy_strerror(conncode));\r
3324 \r
3325                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
3326                                         GetHTTPCode());\r
3327 \r
3328                         return wxT("");\r
3329                 \r
3330                 } else {\r
3331 \r
3332                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3333                                         curl_easy_strerror(conncode));\r
3334                         return wxT("");\r
3335 \r
3336                 }\r
3337 \r
3338         }\r
3339         \r
3340         // Process the XML data from the application.\r
3341         \r
3342         xmlDocPtr xmlCardDAVDoc;\r
3343         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
3344 \r
3345         xmlNodePtr nodeLevel1;\r
3346         xmlNodePtr nodeLevel2;\r
3347         xmlNodePtr nodeLevel3;\r
3348         xmlNodePtr nodeLevel4;\r
3349         xmlNodePtr nodeLevel5;\r
3350         xmlNodePtr nodeLevel6;\r
3351         xmlNodePtr nodeLevel7;\r
3352                 \r
3353         for (nodeLevel1 = xmlCardDAVDoc->children;\r
3354                 nodeLevel1 != NULL;\r
3355                 nodeLevel1 = nodeLevel1->next)\r
3356         {\r
3357 \r
3358                 for (nodeLevel2 = nodeLevel1->children;\r
3359                         nodeLevel2 != NULL;\r
3360                         nodeLevel2 = nodeLevel2->next)\r
3361                 {\r
3362 \r
3363 \r
3364                         for (nodeLevel3 = nodeLevel2->children;\r
3365                         nodeLevel3 != NULL;\r
3366                         nodeLevel3 = nodeLevel3->next)\r
3367                         {\r
3368                         \r
3369                                 for (nodeLevel4 = nodeLevel3->children;\r
3370                                 nodeLevel4 != NULL;\r
3371                                 nodeLevel4 = nodeLevel4->next)\r
3372                                 {\r
3373                         \r
3374                                         for (nodeLevel5 = nodeLevel4->children;\r
3375                                         nodeLevel5 != NULL;\r
3376                                         nodeLevel5 = nodeLevel5->next)\r
3377                                         {\r
3378                         \r
3379                                                 for (nodeLevel6 = nodeLevel5->children;\r
3380                                                 nodeLevel6 != NULL;\r
3381                                                 nodeLevel6 = nodeLevel6->next)\r
3382                                                 {\r
3383                         \r
3384                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
3385                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
3386                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
3387                                                         ){\r
3388                         \r
3389                                                                 // Found the <href> part so extract the principal URL address.\r
3390                                                                 \r
3391                                                                 for (nodeLevel7 = nodeLevel6->children;\r
3392                                                                 nodeLevel7 != NULL;\r
3393                                                                 nodeLevel7 = nodeLevel7->next)\r
3394                                                                 {\r
3395                                                                 \r
3396                                                                         SAURLPrincipalURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));\r
3397                         \r
3398                                                                 }\r
3399                         \r
3400                                                         }\r
3401                         \r
3402                                                 }\r
3403                         \r
3404                                         }\r
3405                         \r
3406                                 }\r
3407                         \r
3408                         }\r
3409                 \r
3410                 }\r
3411                 \r
3412         }\r
3413         \r
3414         xmlFreeDoc(xmlCardDAVDoc);\r
3415         PageData.Clear();\r
3416         PageHeader.Clear();\r
3417                 \r
3418         // Second: Get the addressbook-home-set \r
3419 \r
3420         curl_easy_reset(conn);\r
3421 \r
3422         if (ServerSSL){\r
3423 \r
3424                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
3425                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
3426                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
3427                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3428                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
3429                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
3430                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3431                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3432                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3433                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3434                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3435 \r
3436                 if (UploadMode == TRUE){\r
3437 \r
3438                         UploadData.readptr = &ServerUploadData;\r
3439                         UploadData.sizeleft = ServerUploadData.Len();\r
3440                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
3441                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
3442                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
3443                 \r
3444                 }\r
3445 \r
3446                 conncode = (curl_easy_perform(conn));\r
3447 \r
3448                 if (conncode == CURLE_OK){\r
3449 \r
3450                         *ServerResult = TRUE;\r
3451                         AuthPassed = TRUE;\r
3452                         SSLStatus = TRUE;\r
3453                         return wxT("");\r
3454 \r
3455                 } else {\r
3456 \r
3457                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3458                                         curl_easy_strerror(conncode));                                  \r
3459                                         \r
3460                         *ServerResult = FALSE;\r
3461                         \r
3462                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3463                         \r
3464                         return wxT("");                                 \r
3465 \r
3466                 }\r
3467 \r
3468         } else {\r
3469         \r
3470         // No SSL.\r
3471                 \r
3472                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8));\r
3473                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
3474                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
3475                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3476                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
3477                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
3478                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3479                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3480                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3481                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3482                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
3483                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
3484                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3485                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
3486                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2);\r
3487                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2));\r
3488                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2);\r
3489                 \r
3490                 conncode = (curl_easy_perform(conn));\r
3491                 \r
3492                 // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
3493                 // then bring up the conflict resolution form.\r
3494                 \r
3495                 if (EditMode == TRUE){\r
3496                 \r
3497                 }\r
3498 \r
3499                 if (conncode == CURLE_OK){\r
3500 \r
3501                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
3502 \r
3503                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3504                 \r
3505                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3506                                         curl_easy_strerror(conncode));\r
3507 \r
3508                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
3509                                         GetHTTPCode());\r
3510                         return wxT("");\r
3511                 \r
3512                 } else {\r
3513 \r
3514                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3515                                         curl_easy_strerror(conncode));\r
3516                         return wxT("");\r
3517 \r
3518                 }\r
3519                 \r
3520         }\r
3521 \r
3522         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
3523                 \r
3524         for (nodeLevel1 = xmlCardDAVDoc->children;\r
3525                 nodeLevel1 != NULL;\r
3526                 nodeLevel1 = nodeLevel1->next)\r
3527         {\r
3528 \r
3529                 for (nodeLevel2 = nodeLevel1->children;\r
3530                         nodeLevel2 != NULL;\r
3531                         nodeLevel2 = nodeLevel2->next)\r
3532                 {\r
3533 \r
3534 \r
3535                         for (nodeLevel3 = nodeLevel2->children;\r
3536                         nodeLevel3 != NULL;\r
3537                         nodeLevel3 = nodeLevel3->next)\r
3538                         {\r
3539                         \r
3540                                 for (nodeLevel4 = nodeLevel3->children;\r
3541                                 nodeLevel4 != NULL;\r
3542                                 nodeLevel4 = nodeLevel4->next)\r
3543                                 {\r
3544                         \r
3545                                         for (nodeLevel5 = nodeLevel4->children;\r
3546                                         nodeLevel5 != NULL;\r
3547                                         nodeLevel5 = nodeLevel5->next)\r
3548                                         {\r
3549                         \r
3550                                                 for (nodeLevel6 = nodeLevel5->children;\r
3551                                                 nodeLevel6 != NULL;\r
3552                                                 nodeLevel6 = nodeLevel6->next)\r
3553                                                 {\r
3554                         \r
3555                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
3556                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
3557                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
3558                                                         ){\r
3559                         \r
3560                                                                 // Found the <href> part so extract the principal URL address.\r
3561                                                                 \r
3562                                                                 for (nodeLevel7 = nodeLevel6->children;\r
3563                                                                 nodeLevel7 != NULL;\r
3564                                                                 nodeLevel7 = nodeLevel7->next)\r
3565                                                                 {\r
3566                                                                 \r
3567                                                                         SAURLAddressURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));\r
3568                         \r
3569                                                                 }\r
3570                         \r
3571                                                         }\r
3572                         \r
3573                                                 }\r
3574                         \r
3575                                         }\r
3576                         \r
3577                                 }\r
3578                         \r
3579                         }\r
3580                 \r
3581                 }\r
3582                 \r
3583         }\r
3584 \r
3585         xmlFreeDoc(xmlCardDAVDoc);\r
3586         PageData.Clear();\r
3587         PageHeader.Clear();\r
3588 \r
3589         // Finally: Get the default-addressbook-URL from the addressbook-home-set address.\r
3590                 \r
3591         curl_easy_reset(conn);\r
3592 \r
3593         if (ServerSSL){\r
3594 \r
3595                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
3596                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
3597                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
3598                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3599                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
3600                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
3601                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3602                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3603                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3604                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3605                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3606 \r
3607                 if (UploadMode == TRUE){\r
3608 \r
3609                         UploadData.readptr = &ServerUploadData;\r
3610                         UploadData.sizeleft = ServerUploadData.Len();\r
3611                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
3612                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
3613                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
3614                 \r
3615                 }\r
3616 \r
3617                 conncode = (curl_easy_perform(conn));\r
3618 \r
3619                 if (conncode == CURLE_OK){\r
3620 \r
3621                         *ServerResult = TRUE;\r
3622                         AuthPassed = TRUE;\r
3623                         SSLStatus = TRUE;\r
3624                         return wxT("");\r
3625 \r
3626                 } else {\r
3627 \r
3628                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3629                                         curl_easy_strerror(conncode));                                  \r
3630                                         \r
3631                         *ServerResult = FALSE;\r
3632                         \r
3633                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3634                         \r
3635                         return wxT("");                                 \r
3636 \r
3637                 }\r
3638 \r
3639         } else {\r
3640         \r
3641         // No SSL.\r
3642                 \r
3643                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8));\r
3644                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
3645                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
3646                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
3647                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
3648                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
3649                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
3650                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
3651                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
3652                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
3653                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
3654                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
3655                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
3656                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
3657                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3);\r
3658                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3));\r
3659                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3);\r
3660                 \r
3661                 conncode = (curl_easy_perform(conn));\r
3662                 \r
3663                 // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
3664                 // then bring up the conflict resolution form.\r
3665                 \r
3666                 if (EditMode == TRUE){\r
3667                 \r
3668                 }\r
3669 \r
3670                 if (conncode == CURLE_OK){\r
3671 \r
3672                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
3673 \r
3674                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
3675                 \r
3676                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3677                                         curl_easy_strerror(conncode));\r
3678 \r
3679                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
3680                                         GetHTTPCode());\r
3681                         return wxT("");\r
3682                 \r
3683                 } else {\r
3684 \r
3685                         fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
3686                                         curl_easy_strerror(conncode));\r
3687                         return wxT("");\r
3688 \r
3689                 }\r
3690                 \r
3691         }\r
3692         \r
3693         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
3694                 \r
3695         for (nodeLevel1 = xmlCardDAVDoc->children;\r
3696                 nodeLevel1 != NULL;\r
3697                 nodeLevel1 = nodeLevel1->next)\r
3698         {\r
3699 \r
3700                 for (nodeLevel2 = nodeLevel1->children;\r
3701                         nodeLevel2 != NULL;\r
3702                         nodeLevel2 = nodeLevel2->next)\r
3703                 {\r
3704 \r
3705 \r
3706                         for (nodeLevel3 = nodeLevel2->children;\r
3707                         nodeLevel3 != NULL;\r
3708                         nodeLevel3 = nodeLevel3->next)\r
3709                         {\r
3710                         \r
3711                                 for (nodeLevel4 = nodeLevel3->children;\r
3712                                 nodeLevel4 != NULL;\r
3713                                 nodeLevel4 = nodeLevel4->next)\r
3714                                 {\r
3715                         \r
3716                                         for (nodeLevel5 = nodeLevel4->children;\r
3717                                         nodeLevel5 != NULL;\r
3718                                         nodeLevel5 = nodeLevel5->next)\r
3719                                         {\r
3720                         \r
3721                                                 for (nodeLevel6 = nodeLevel5->children;\r
3722                                                 nodeLevel6 != NULL;\r
3723                                                 nodeLevel6 = nodeLevel6->next)\r
3724                                                 {\r
3725                         \r
3726                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
3727                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
3728                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
3729                                                         ){\r
3730                         \r
3731                                                                 // Found the <href> part so extract the principal URL address.\r
3732                                                                 \r
3733                                                                 for (nodeLevel7 = nodeLevel6->children;\r
3734                                                                 nodeLevel7 != NULL;\r
3735                                                                 nodeLevel7 = nodeLevel7->next)\r
3736                                                                 {\r
3737                                                                 \r
3738                                                                         FinalPrefix = wxString::FromUTF8((const char*)nodeLevel7->content);\r
3739                         \r
3740                                                                 }\r
3741                         \r
3742                                                         }\r
3743                         \r
3744                                                 }\r
3745                         \r
3746                                         }\r
3747                         \r
3748                                 }\r
3749                         \r
3750                         }\r
3751                 \r
3752                 }\r
3753                 \r
3754         }\r
3755 \r
3756         xmlFreeDoc(xmlCardDAVDoc);\r
3757         PageData.Clear();\r
3758         PageHeader.Clear();\r
3759 \r
3760         return FinalPrefix;\r
3761 \r
3762 }\r
3763 \r
3764 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){\r
3765 \r
3766         SSLCertCollection SSLCertInfo;\r
3767 \r
3768         // Grab the certificate data.\r
3769 \r
3770         union {\r
3771                 struct curl_slist *certdata;\r
3772                 struct curl_certinfo *certinfo;\r
3773         } certptr;\r
3774 \r
3775         certptr.certdata = NULL;\r
3776         \r
3777         curl_easy_getinfo(conn, CURLINFO_CERTINFO, &certptr.certinfo);\r
3778 \r
3779         wxString CertPropName;\r
3780         wxString CertPropValue;\r
3781 \r
3782         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){\r
3783 \r
3784                 struct curl_slist *slist;\r
3785                 SSLCertData SSLCertDataInc;\r
3786                 \r
3787                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){\r
3788                         \r
3789                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");\r
3790                         \r
3791                         // Get first token as the property name.\r
3792                         \r
3793                         CertPropName = CertDataInc.GetNextToken();\r
3794                         \r
3795                         // Get remaining tokens as the property value.\r
3796                         \r
3797                         while(CertDataInc.HasMoreTokens()){\r
3798                         \r
3799                                 CertPropValue.Append(CertDataInc.GetNextToken());\r
3800                         \r
3801                         }\r
3802                         \r
3803                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));\r
3804                         CertPropName.clear();\r
3805                         CertPropValue.clear();\r
3806                         \r
3807                 }\r
3808         \r
3809                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));\r
3810         \r
3811         }\r
3812         \r
3813         return SSLCertInfo;\r
3814 \r
3815 }\r
3816 \r
3817 SSLCertCollection CardDAV::GetCertificateData(){\r
3818 \r
3819         // Pass on the collected certificate data.\r
3820 \r
3821         return SSLCertCol;\r
3822 \r
3823 }\r
3824 \r
3825 wxString CardDAV::GetErrorMessage(){\r
3826 \r
3827         return ErrorMessage;\r
3828 \r
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