Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added copyright and license headers on C++ source and header files in the carddav...
[xestiaab/.git] / source / carddav / carddav-servercontact.cpp
1 // carddav-servercontact.cpp - CardDAV Object - Server Contact subroutines.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
10 //
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "carddav.h"
20 #include "../version.h"
21 #include <wx/wx.h>
22 #include <wx/tokenzr.h>
23 #include <wx/ffile.h>
24 #include <libxml/parser.h>
25 #include <libxml/tree.h>
26 #include <map>
27 #include <thread>
28 #include "../vcard/vcard.h"
29 #include "../common/dirs.h"
31 void CardDAV::GetServerContactData()
32 {
34         PageData.Clear();
35         PageHeader.Clear();
37         SSLStatus = TRUE;
38         AuthPassed = TRUE;
39         AbortConnection = FALSE;
40         
41         wxString ServerCertFilename;
42         bool MatchingCert = FALSE;
44         CURL *conn;
45         CURLcode conncode;
46         wxString ServerAddressURL;
47         wxString ServerAuth;
48         wxString ServerAddressSSL;
49         wxString ServerAddressNormal;   
51         conn = curl_easy_init();
52         
53         struct CardDAVCURLPasser {
54         
55                 CardDAV *Data;
56                 bool HeaderMode = TRUE;
57         
58         } CardDAVHeader, CardDAVFooter;
60         CardDAVHeader.Data = this;
61         CardDAVHeader.HeaderMode = TRUE;
62         
63         CardDAVFooter.Data = this;
64         CardDAVFooter.HeaderMode = FALSE;
66         wxString Data1;
67         wxString Data2;
68         
69         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
70         ServerAddressSSL = wxT("https://") + ServerAddressURL;
71         ServerAddressNormal = wxT("http://") + ServerAddressURL;
72         
73         ServerAuth = ServerUser + wxT(":") + ServerPass;
74         
75         // Try SSL first.
78         /*
79         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
80         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
81         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
82         
83         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
84         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
85         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
87         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
88         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
89         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
90         
91         */
93         //std::string WriteDataString = std::string(ServerUploadData.mb_str());
95         std::map<int,int>::iterator ActIter;
96         struct UploadDataStruc UploadData;
97         
98         
99         ActIter = ActivityListPtr->find((int)ItemIndex);
101         //ActIter->second = 1;
103         /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
104         CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));
105         CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));
106         CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));
107         CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));
108         CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));
109         CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));
110         CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/
112         if (ServerSSL){
114                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
115                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
116                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
117                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
118                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
119                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
120                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
121                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
122                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
123                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
124                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
125                 
126                 //UploadData.readptr = &CardDAVDataQuery;
127                 //UploadData.sizeleft = CardDAVDataQuery.Len();
128                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
129                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
130                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
132                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
134                 if (wxFile::Exists(ServerCertFilename) == TRUE){
135                 
136                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
137                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
138                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
139                 
140                 }
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, 1L);
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_NOSIGNAL, 1);
163                 
164                         //UploadData.readptr = &CardDAVDataQuery;
165                         //UploadData.sizeleft = CardDAVDataQuery.Len();
166                         
167                         claconncode = (curl_easy_perform(conn));
168                         
169                         // If claconncode is CURLE_OK then delete the certificate file as that
170                         // is no longer needed.
171                         
172                         if (claconncode == CURLE_OK){
173                         
174                                 // Delete the certificate file.
175                                 
176                                 wxRemoveFile(ServerCertFilename);
177                         
178                         }
179                 
180                 }
182                 // Check if it fails with a CURLE_SSL_CACERT then compare
183                 // the certificates as PEM files.
184                 
185                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
186                 
187                         //curl_easy_cleanup(conn);
188                         //conn = curl_easy_init();
190                         CURL *sslerrconn;
191                         sslerrconn = curl_easy_init();
192                         CURLcode sslerrconncode;
194                         //claconncode = (curl_easy_perform(conn));
196                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
198                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
199                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);
200                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
201                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
202                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
203                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               
204                         curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
205                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
206                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
207                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
208                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
209                 
210                         //UploadData.readptr = &CardDAVDataQuery;
211                         //UploadData.sizeleft = CardDAVDataQuery.Len();
212                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
213                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);
214                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
215                 
216                         wxString SSLLocalData;
217                         wxString SSLServerData;
218                 
219                         sslerrconncode = (curl_easy_perform(sslerrconn));
220                 
221                         SSLCertCol = BuildSSLCollection(sslerrconn);
222                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
223                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
224                         
225                         wxFFile SSLLocalFile;
226                         
227 #if wxABI_VERSION < 20900
228                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
229 #else
230                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
231 #endif  
232         
233                         // Load the recovery database for tasks not done.
234         
235                         if (SSLLocalFile.IsOpened() == TRUE){
236         
237                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
238                 
239         
240                         }
241                         
242                         SSLServerData = SSLDataIter->second;
243                         
244                         if (SSLLocalData == SSLServerData){
245                         
246                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
247                                 // and CURLOPT_SSL_VERIFYHOST off.
248                         
249                                 curl_easy_cleanup(conn);
250                                 conn = curl_easy_init();
251                                 
252                                 PageData.clear();
253                                 PageHeader.clear();
254                         
255                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
256                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
257                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
258                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
259                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
260                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
261                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
262                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
263                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
264                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
265                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
266                 
267                                 //UploadData.readptr = &CardDAVDataQuery;
268                                 //UploadData.sizeleft = CardDAVDataQuery.Len();
269                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
270                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
271                                                         
272                                 claconncode = (curl_easy_perform(conn));
273                                 
274                                 MatchingCert = TRUE;
275                         
276                         }
277                         
278                         if (MatchingCert == FALSE){
279                 
280                                 claconncode = CURLE_SSL_CACERT;
281                                 return;
282                 
283                         }
284                         
285                         curl_easy_cleanup(sslerrconn);
286                 
287                 }
288                 
289                 // Sort out SSL error.
290                 
291                 // When SSL cert error occurs, connect again and fetch certificates.
292                 // Display a message to the user explaining that an invalid
293                 // certificate has been given and let the user decide what
294                 // to do next.
296                 if (claconncode == CURLE_OK){
298                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
299                 
300                         CURL *sslerrconn;
301                         sslerrconn = curl_easy_init();
302                         CURLcode sslerrconncode;
303                 
304                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
305                 
306                         // Replace conn with sslerrconn!
307                 
308                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
309                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
310                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
311                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
312                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
313                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
314                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
315                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
316                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
317                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
318                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
319                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
320                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
321                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
322                                         
323                         sslerrconncode = (curl_easy_perform(sslerrconn));
325                         SSLCertCol = BuildSSLCollection(sslerrconn);
326                         SSLCertCol.SuccessCode = 1;
328                         return;
329                 
330                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
331                 
332                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
333                                         curl_easy_strerror(claconncode));
334                         int http_code = 0;
335                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
336                         fprintf(stderr, "Error code was: %d\n", http_code);
337                                         
338                         return;
339                 
340                 } else {
342                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
343                                         curl_easy_strerror(claconncode));
344                         int http_code = 0;
345                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
346                         fprintf(stderr, "Error code was: %d\n", http_code);
348                         return;
350                 }
351                 
352         } else {
353         
354                 // No SSL.
355                 
356                 wxString EmptyString;
357                 
358                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
359                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
360                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
361                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
362                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
363                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
364                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
365                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
366                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
367                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
368                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
369                 
370                 //UploadData.readptr = &CardDAVDataQuery;
371                 //UploadData.sizeleft = CardDAVDataQuery.Len();
372                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
373                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
374                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
376                 //UploadData.readptr = &CardDAVDataQuery;
377                 //UploadData.sizeleft = CardDAVDataQuery.Len();
378                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
379                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
380                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
381                 
382                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     
383                 
384                 PageData.Clear();
385                 PageHeader.Clear();
386                 
387                 conncode = (curl_easy_perform(conn));
389                 if (conncode == CURLE_OK){
391                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
392                 
393                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
394                                         curl_easy_strerror(conncode));
395                                         
396                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
397                                         GetHTTPCode());
398                                         
399                         return;
400                 
401                 } else {
403                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
404                                         curl_easy_strerror(conncode));
405                                 
406                         return;
408                 }
409                 
410         }
411         
412         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