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-servercontact.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::GetServerContactData()
14 {
16         PageData.Clear();
17         PageHeader.Clear();
19         SSLStatus = TRUE;
20         AuthPassed = TRUE;
21         AbortConnection = FALSE;
22         
23         wxString ServerCertFilename;
24         bool MatchingCert = FALSE;
26         CURL *conn;
27         CURLcode conncode;
28         wxString ServerAddressURL;
29         wxString ServerAuth;
30         wxString ServerAddressSSL;
31         wxString ServerAddressNormal;   
33         conn = curl_easy_init();
34         
35         struct CardDAVCURLPasser {
36         
37                 CardDAV *Data;
38                 bool HeaderMode = TRUE;
39         
40         } CardDAVHeader, CardDAVFooter;
42         CardDAVHeader.Data = this;
43         CardDAVHeader.HeaderMode = TRUE;
44         
45         CardDAVFooter.Data = this;
46         CardDAVFooter.HeaderMode = FALSE;
48         wxString Data1;
49         wxString Data2;
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);
83         //ActIter->second = 1;
85         /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
86         CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));
87         CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));
88         CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));
89         CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));
90         CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));
91         CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));
92         CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/
94         if (ServerSSL){
96                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
97                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
98                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
99                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
100                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
101                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
102                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
103                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
104                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
105                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
106                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
107                 
108                 //UploadData.readptr = &CardDAVDataQuery;
109                 //UploadData.sizeleft = CardDAVDataQuery.Len();
110                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
111                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
112                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
114                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
116                 if (wxFile::Exists(ServerCertFilename) == TRUE){
117                 
118                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
119                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
120                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
121                 
122                 }
124                 claconncode = (curl_easy_perform(conn));
126                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
127                 // the local certificate in use.
129                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
130                         
131                         curl_easy_cleanup(conn);
132                         conn = curl_easy_init();
133                         
134                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
135                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
136                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
137                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
138                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
139                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
140                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
141                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
142                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
143                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
144                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
145                 
146                         //UploadData.readptr = &CardDAVDataQuery;
147                         //UploadData.sizeleft = CardDAVDataQuery.Len();
148                         
149                         claconncode = (curl_easy_perform(conn));
150                         
151                         // If claconncode is CURLE_OK then delete the certificate file as that
152                         // is no longer needed.
153                         
154                         if (claconncode == CURLE_OK){
155                         
156                                 // Delete the certificate file.
157                                 
158                                 wxRemoveFile(ServerCertFilename);
159                         
160                         }
161                 
162                 }
164                 // Check if it fails with a CURLE_SSL_CACERT then compare
165                 // the certificates as PEM files.
166                 
167                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
168                 
169                         //curl_easy_cleanup(conn);
170                         //conn = curl_easy_init();
172                         CURL *sslerrconn;
173                         sslerrconn = curl_easy_init();
174                         CURLcode sslerrconncode;
176                         //claconncode = (curl_easy_perform(conn));
178                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
180                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
181                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);
182                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
183                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
184                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
185                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               
186                         curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
187                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
188                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
189                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
190                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
191                 
192                         //UploadData.readptr = &CardDAVDataQuery;
193                         //UploadData.sizeleft = CardDAVDataQuery.Len();
194                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
195                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);
196                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
197                 
198                         wxString SSLLocalData;
199                         wxString SSLServerData;
200                 
201                         sslerrconncode = (curl_easy_perform(sslerrconn));
202                 
203                         SSLCertCol = BuildSSLCollection(sslerrconn);
204                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
205                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
206                         
207                         wxFFile SSLLocalFile;
208                         
209 #if wxABI_VERSION < 20900
210                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
211 #else
212                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
213 #endif  
214         
215                         // Load the recovery database for tasks not done.
216         
217                         if (SSLLocalFile.IsOpened() == TRUE){
218         
219                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
220                 
221         
222                         }
223                         
224                         SSLServerData = SSLDataIter->second;
225                         
226                         if (SSLLocalData == SSLServerData){
227                         
228                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
229                                 // and CURLOPT_SSL_VERIFYHOST off.
230                         
231                                 curl_easy_cleanup(conn);
232                                 conn = curl_easy_init();
233                                 
234                                 PageData.clear();
235                                 PageHeader.clear();
236                         
237                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
238                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
239                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
240                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
241                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
242                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
243                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
244                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
245                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
246                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
247                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
248                 
249                                 //UploadData.readptr = &CardDAVDataQuery;
250                                 //UploadData.sizeleft = CardDAVDataQuery.Len();
251                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
252                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
253                                                         
254                                 claconncode = (curl_easy_perform(conn));
255                                 
256                                 MatchingCert = TRUE;
257                         
258                         }
259                         
260                         if (MatchingCert == FALSE){
261                 
262                                 claconncode = CURLE_SSL_CACERT;
263                                 return;
264                 
265                         }
266                         
267                         curl_easy_cleanup(sslerrconn);
268                 
269                 }
270                 
271                 // Sort out SSL error.
272                 
273                 // When SSL cert error occurs, connect again and fetch certificates.
274                 // Display a message to the user explaining that an invalid
275                 // certificate has been given and let the user decide what
276                 // to do next.
278                 if (claconncode == CURLE_OK){
280                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
281                 
282                         CURL *sslerrconn;
283                         sslerrconn = curl_easy_init();
284                         CURLcode sslerrconncode;
285                 
286                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
287                 
288                         // Replace conn with sslerrconn!
289                 
290                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
291                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
292                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
293                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
294                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
295                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
296                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
297                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
298                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
299                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
300                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
301                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
302                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
303                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
304                                         
305                         sslerrconncode = (curl_easy_perform(sslerrconn));
307                         SSLCertCol = BuildSSLCollection(sslerrconn);
308                         SSLCertCol.SuccessCode = 1;
310                         return;
311                 
312                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
313                 
314                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
315                                         curl_easy_strerror(claconncode));
316                         int http_code = 0;
317                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
318                         fprintf(stderr, "Error code was: %d\n", http_code);
319                                         
320                         return;
321                 
322                 } else {
324                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
325                                         curl_easy_strerror(claconncode));
326                         int http_code = 0;
327                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
328                         fprintf(stderr, "Error code was: %d\n", http_code);
330                         return;
332                 }
333                 
334         } else {
335         
336                 // No SSL.
337                 
338                 wxString EmptyString;
339                 
340                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
341                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
342                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
343                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
344                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
345                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
346                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
347                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
348                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
349                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
350                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
351                 
352                 //UploadData.readptr = &CardDAVDataQuery;
353                 //UploadData.sizeleft = CardDAVDataQuery.Len();
354                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
355                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
356                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
358                 //UploadData.readptr = &CardDAVDataQuery;
359                 //UploadData.sizeleft = CardDAVDataQuery.Len();
360                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
361                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
362                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
363                 
364                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     
365                 
366                 PageData.Clear();
367                 PageHeader.Clear();
368                 
369                 conncode = (curl_easy_perform(conn));
371                 if (conncode == CURLE_OK){
373                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
374                 
375                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
376                                         curl_easy_strerror(conncode));
377                                         
378                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
379                                         GetHTTPCode());
380                                         
381                         return;
382                 
383                 } else {
385                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
386                                         curl_easy_strerror(conncode));
387                                 
388                         return;
390                 }
391                 
392         }
393         
394         return;
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