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