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