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