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