Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Split carddav/carddav.cpp down into 8 files to make it manageable.
[xestiaab/.git] / source / carddav / carddav-processdata.cpp
1 #include "carddav.h"
2 #include "../version.h"
3 #include <wx/wx.h>
4 #include <wx/tokenzr.h>
5 #include <wx/ffile.h>
6 #include <libxml/parser.h>
7 #include <libxml/tree.h>
8 #include <map>
9 #include <thread>
10 #include "../vcard/vcard.h"
11 #include "../common/dirs.h"
13 void CardDAV::ProcessDataThread(){
15         PageData.Clear();
16         PageHeader.Clear();
18         SSLStatus = TRUE;
19         AuthPassed = TRUE;
20         AbortConnection = FALSE;
22         CURL *conn;
23         CURLcode conncode;
24         wxString ServerAddressURL;
25         wxString ServerAuth;
26         wxString ServerAddressSSL;
27         wxString ServerAddressNormal;   
29         conn = curl_easy_init();
30         
31         struct CardDAVCURLPasser {
32         
33                 CardDAV *Data;
34                 bool HeaderMode = TRUE;
35         
36         } CardDAVHeader, CardDAVFooter;
38         CardDAVHeader.Data = this;
39         CardDAVHeader.HeaderMode = TRUE;
40         
41         CardDAVFooter.Data = this;
42         CardDAVFooter.HeaderMode = FALSE;
44         wxString Data1;
45         wxString Data2;
46         
47         wxString ETag;
48         wxString ETagOriginal;
49         wxString ETagServer;
50                 
51         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
52         ServerAddressSSL = wxT("https://") + ServerAddressURL;
53         ServerAddressNormal = wxT("http://") + ServerAddressURL;
54         
55         ServerAuth = ServerUser + wxT(":") + ServerPass;
56         
57         // Try SSL first.
60         /*
61         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
62         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
63         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
64         
65         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
66         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
67         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
69         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
70         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
71         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
72         
73         */
75         //std::string WriteDataString = std::string(ServerUploadData.mb_str());
77         std::map<int,int>::iterator ActIter;
78         struct UploadDataStruc UploadData;
79         
80         
81         ActIter = ActivityListPtr->find((int)ItemIndex);
82         
83         // Update result flag.
85         ActIter->second = 1;
86         
87         // Setup the request mode if it is not empty.
88         
89         if (!ServerMethod.IsEmpty()){
90         
91                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8));
93         }
95         if (ServerSSL){
97                 wxString ServerCertFilename;
98                 bool MatchingCert = FALSE;
100                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
101                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
102                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
103                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
104                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
105                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
106                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
107                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
108                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
109                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
110                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
111                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
112                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
113                 
114                 if (UploadMode == TRUE){
115                         
116                         UploadData.readptr = &ServerUploadData;
117                         UploadData.sizeleft = ServerUploadData.Len();
118                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
119                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
120                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
121                 
122                 }
124                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
126                 if (wxFile::Exists(ServerCertFilename) == TRUE){
127                 
128                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
129                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
130                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
131                 
132                 }
134                 //UploadData.readptr = &CardDAVDataQuery;
135                 //UploadData.sizeleft = CardDAVDataQuery.Len();
136                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
137                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
138                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
139                 
140                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
141                 
142                 claconncode = (curl_easy_perform(conn));
144                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
145                 // the local certificate in use.
147                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
148                         
149                         curl_easy_cleanup(conn);
150                         conn = curl_easy_init();
151                         
152                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
153                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
154                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
155                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
156                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
157                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
158                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
159                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
160                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
161                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
162                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
163                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
164                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
166                         if (UploadMode == TRUE){
168                                 UploadData.readptr = &ServerUploadData;
169                                 UploadData.sizeleft = ServerUploadData.Len();
170                                 curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
171                                 curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
172                                 curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
173                 
174                         }
175                         
176                         claconncode = (curl_easy_perform(conn));
177                         
178                         // If claconncode is CURLE_OK then delete the certificate file as that
179                         // is no longer needed.
180                         
181                         if (claconncode == CURLE_OK){
182                         
183                                 // Delete the certificate file.
184                                 
185                                 wxRemoveFile(ServerCertFilename);
186                         
187                         }
188                 
189                 }
191                 // Check if it fails with a CURLE_SSL_CACERT then compare
192                 // the certificates as PEM files.
193                 
194                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
195                 
196                         //curl_easy_cleanup(conn);
197                         //conn = curl_easy_init();
199                         CURL *sslerrconn;
200                         sslerrconn = curl_easy_init();
201                         CURLcode sslerrconncode;
203                         //claconncode = (curl_easy_perform(conn));
205                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
207                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
208                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
209                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
210                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
211                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
212                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
213                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
214                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
215                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
216                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
217                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
218                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
219                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
220                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
221                 
222                         wxString SSLLocalData;
223                         wxString SSLServerData;
224                 
225                         sslerrconncode = (curl_easy_perform(sslerrconn));
226                 
227                         SSLCertCol = BuildSSLCollection(sslerrconn);
228                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
229                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
230                         
231                         wxFFile SSLLocalFile;
232                         
233 #if wxABI_VERSION < 20900
234                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
235 #else
236                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
237 #endif  
238         
239                         // Load the recovery database for tasks not done.
240         
241                         if (SSLLocalFile.IsOpened() == TRUE){
243                         // Check if we are using wxWidgets version 2.8 or less and
244                         // execute the required command accordingly.
245         
246                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
247                 
248         
249                         }
250                         
251                         SSLServerData = SSLDataIter->second;
252                         
253                         if (SSLLocalData == SSLServerData){
254                         
255                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
256                                 // and CURLOPT_SSL_VERIFYHOST off.
257                         
258                                 curl_easy_cleanup(conn);
259                                 conn = curl_easy_init();
260                                 
261                                 PageData.clear();
262                                 PageHeader.clear();
263                         
264                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
265                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
266                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
267                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
268                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
269                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
270                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
271                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
272                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
273                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
274                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
275                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
276                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
278                                 if (UploadMode == TRUE){
280                                         UploadData.readptr = &ServerUploadData;
281                                         UploadData.sizeleft = ServerUploadData.Len();
282                                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
283                                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
284                                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
285                 
286                                 }
287                                 
288                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
289                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
290                         
291                                 claconncode = (curl_easy_perform(conn));
292                                 
293                                 MatchingCert = TRUE;
294                         
295                         }
296                         
297                         if (MatchingCert == FALSE){
298                 
299                                 claconncode = CURLE_SSL_CACERT;
300                                 return;
301                 
302                         }
303                         
304                         curl_easy_cleanup(sslerrconn);
305                 
306                 }
308                 // Sort out SSL error.
309                 
310                 // When SSL cert error occurs, connect again and fetch certificates.
311                 // Display a message to the user explaining that an invalid
312                 // certificate has been given and let the user decide what
313                 // to do next.
315                 if (claconncode == CURLE_OK){
317                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
318                 
319                         CURL *sslerrconn;
320                         sslerrconn = curl_easy_init();
321                         CURLcode sslerrconncode;
322                 
323                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
324                 
325                         // Replace conn with sslerrconn!
326                 
327                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
328                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
329                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
330                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
331                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
332                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
333                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
334                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
335                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
336                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
337                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
338                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
339                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
340                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
341                 
342                         sslerrconncode = (curl_easy_perform(sslerrconn));
344                         SSLCertCol = BuildSSLCollection(sslerrconn);
345                         SSLCertCol.SuccessCode = 1;
347                         return;
348                 
349                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
350                 
351                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
352                                         curl_easy_strerror(claconncode));
353                         int http_code = 0;
354                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
355                         fprintf(stderr, "Error code was: %d\n", http_code);
356                                         
357                         return;
358                 
359                 } else {
361                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
362                                         curl_easy_strerror(claconncode));
363                         int http_code = 0;
364                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
365                         fprintf(stderr, "Error code was: %d\n", http_code);
367                         return;
369                 }
371         } else {
372         
373         // No SSL.
374                 
375                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
376                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
377                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
378                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
379                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
380                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
381                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
382                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
383                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
384                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
385                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
386                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
387                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
388                 
389                 if (UploadMode == TRUE){
390                         
391                         UploadData.readptr = &ServerUploadData;
392                         UploadData.sizeleft = ServerUploadData.Len();
393                         curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
394                         curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
395                         curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
396                 
397                 }
398                 
399                 conncode = (curl_easy_perform(conn));
401                 if (conncode == CURLE_OK){
403                         // Process the server header response and look for
404                         // 'addressbook' within the DAV header.
405                         
406                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
407                         wxString wxSHeaderLine;
408                         std::map<int, wxString> DAVHeaderLines;
409                         
410                         while (wxSHeaderLines.HasMoreTokens()){
411                         
412                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();
413                                 
414                                 if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){
415                                 
416                                         ETagData = wxSHeaderLine.Mid(5);
417                                         ETagData.Trim();
418                                         ETagData.Trim(FALSE);
419                                         
420                                         // Check for commas.
421                                         
422                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
423                                                         
424                                                 ETagData.Remove(0, 1);
425                                                 ETagData.RemoveLast();
426                                                         
427                                         }
428                                 
429                                 }
430                                 
431                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
432                                 
433                                         // Look for address book in the line.
434                                         
435                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
436                                         
437                                                 HasCalDAVSupport = TRUE;
438                                         
439                                         }
440                                 
441                                 }
442                         
443                         }
444                         
445                         // Get the ETag from the header.
446                         
447                         if (UploadMode == TRUE){
448                 
449                                 wxString PageHeaderLine;
450                 
451                                 wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n"));
452                                 
453                                 if (PageHeaderSplit.HasMoreTokens()){
454                                 
455                                         PageHeaderLine = PageHeaderSplit.GetNextToken();
456                                 
457                                 }
458                 
459                         }
461                         ActIter->second = 4;
462                         return;
464                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
466                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
467                 
468                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
469                                         curl_easy_strerror(conncode));
471                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
472                                         GetHTTPCode());
474                         ActIter->second = 2;
475                         return;
476                 
477                 } else {
479                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
480                                         curl_easy_strerror(conncode));
481                                 
482                         ActIter->second = 2;
483                         return;
485                 }
486                 
487         }
488         
489         // Catch all.
490         
491         //ActIter->second = 1;
492         *ServerResult = TRUE;
493         return;
497 void CardDAV::ProcessData(){
499         std::thread ConnectThread(&CardDAV::ProcessDataThread, this);
500         ConnectThread.detach();
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