Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added comment to describe GetServerContactData in carddav/carddav-servercontact.cpp
[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         // Get the server contact data.
35         
36         PageData.Clear();
37         PageHeader.Clear();
39         SSLStatus = TRUE;
40         AuthPassed = TRUE;
41         AbortConnection = FALSE;
42         
43         wxString ServerCertFilename;
44         bool MatchingCert = FALSE;
46         CURL *conn;
47         CURLcode conncode;
48         wxString ServerAddressURL;
49         wxString ServerAuth;
50         wxString ServerAddressSSL;
51         wxString ServerAddressNormal;   
53         conn = curl_easy_init();
54         
55         struct CardDAVCURLPasser {
56         
57                 CardDAV *Data;
58                 bool HeaderMode = TRUE;
59         
60         } CardDAVHeader, CardDAVFooter;
62         CardDAVHeader.Data = this;
63         CardDAVHeader.HeaderMode = TRUE;
64         
65         CardDAVFooter.Data = this;
66         CardDAVFooter.HeaderMode = FALSE;
68         wxString Data1;
69         wxString Data2;
70         
71         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
72         ServerAddressSSL = wxT("https://") + ServerAddressURL;
73         ServerAddressNormal = wxT("http://") + ServerAddressURL;
74         
75         ServerAuth = ServerUser + wxT(":") + ServerPass;
76         
77         // Try SSL first.
80         /*
81         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
82         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
83         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
84         
85         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
86         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
87         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
89         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
90         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
91         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
92         
93         */
95         //std::string WriteDataString = std::string(ServerUploadData.mb_str());
97         std::map<int,int>::iterator ActIter;
98         struct UploadDataStruc UploadData;
99         
100         
101         ActIter = ActivityListPtr->find((int)ItemIndex);
103         //ActIter->second = 1;
105         /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
106         CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));
107         CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));
108         CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));
109         CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));
110         CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));
111         CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));
112         CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/
114         if (ServerSSL){
116                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
117                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
118                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
119                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
120                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
121                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
122                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
123                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
124                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
125                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
126                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
127                 
128                 //UploadData.readptr = &CardDAVDataQuery;
129                 //UploadData.sizeleft = CardDAVDataQuery.Len();
130                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
131                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
132                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
134                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
136                 if (wxFile::Exists(ServerCertFilename) == TRUE){
137                 
138                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
139                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
140                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
141                 
142                 }
144                 claconncode = (curl_easy_perform(conn));
146                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
147                 // the local certificate in use.
149                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
150                         
151                         curl_easy_cleanup(conn);
152                         conn = curl_easy_init();
153                         
154                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
155                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
156                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
157                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
158                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
159                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
160                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
161                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
162                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
163                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
164                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
165                 
166                         //UploadData.readptr = &CardDAVDataQuery;
167                         //UploadData.sizeleft = CardDAVDataQuery.Len();
168                         
169                         claconncode = (curl_easy_perform(conn));
170                         
171                         // If claconncode is CURLE_OK then delete the certificate file as that
172                         // is no longer needed.
173                         
174                         if (claconncode == CURLE_OK){
175                         
176                                 // Delete the certificate file.
177                                 
178                                 wxRemoveFile(ServerCertFilename);
179                         
180                         }
181                 
182                 }
184                 // Check if it fails with a CURLE_SSL_CACERT then compare
185                 // the certificates as PEM files.
186                 
187                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
188                 
189                         //curl_easy_cleanup(conn);
190                         //conn = curl_easy_init();
192                         CURL *sslerrconn;
193                         sslerrconn = curl_easy_init();
194                         CURLcode sslerrconncode;
196                         //claconncode = (curl_easy_perform(conn));
198                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
200                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
201                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);
202                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
203                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
204                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
205                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               
206                         curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
207                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
208                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
209                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
210                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
211                 
212                         //UploadData.readptr = &CardDAVDataQuery;
213                         //UploadData.sizeleft = CardDAVDataQuery.Len();
214                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
215                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);
216                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
217                 
218                         wxString SSLLocalData;
219                         wxString SSLServerData;
220                 
221                         sslerrconncode = (curl_easy_perform(sslerrconn));
222                 
223                         SSLCertCol = BuildSSLCollection(sslerrconn);
224                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
225                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
226                         
227                         wxFFile SSLLocalFile;
228                         
229 #if wxABI_VERSION < 20900
230                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
231 #else
232                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
233 #endif  
234         
235                         // Load the recovery database for tasks not done.
236         
237                         if (SSLLocalFile.IsOpened() == TRUE){
238         
239                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
240                 
241         
242                         }
243                         
244                         SSLServerData = SSLDataIter->second;
245                         
246                         if (SSLLocalData == SSLServerData){
247                         
248                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
249                                 // and CURLOPT_SSL_VERIFYHOST off.
250                         
251                                 curl_easy_cleanup(conn);
252                                 conn = curl_easy_init();
253                                 
254                                 PageData.clear();
255                                 PageHeader.clear();
256                         
257                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
258                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
259                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
260                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
261                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
262                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
263                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
264                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
265                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
266                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
267                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
268                 
269                                 //UploadData.readptr = &CardDAVDataQuery;
270                                 //UploadData.sizeleft = CardDAVDataQuery.Len();
271                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
272                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
273                                                         
274                                 claconncode = (curl_easy_perform(conn));
275                                 
276                                 MatchingCert = TRUE;
277                         
278                         }
279                         
280                         if (MatchingCert == FALSE){
281                 
282                                 claconncode = CURLE_SSL_CACERT;
283                                 return;
284                 
285                         }
286                         
287                         curl_easy_cleanup(sslerrconn);
288                 
289                 }
290                 
291                 // Sort out SSL error.
292                 
293                 // When SSL cert error occurs, connect again and fetch certificates.
294                 // Display a message to the user explaining that an invalid
295                 // certificate has been given and let the user decide what
296                 // to do next.
298                 if (claconncode == CURLE_OK){
300                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
301                 
302                         CURL *sslerrconn;
303                         sslerrconn = curl_easy_init();
304                         CURLcode sslerrconncode;
305                 
306                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
307                 
308                         // Replace conn with sslerrconn!
309                 
310                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
311                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
312                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
313                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
314                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
315                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
316                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
317                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
318                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
319                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
320                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
321                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
322                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
323                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
324                                         
325                         sslerrconncode = (curl_easy_perform(sslerrconn));
327                         SSLCertCol = BuildSSLCollection(sslerrconn);
328                         SSLCertCol.SuccessCode = 1;
330                         return;
331                 
332                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
333                 
334                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
335                                         curl_easy_strerror(claconncode));
336                         int http_code = 0;
337                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
338                         fprintf(stderr, "Error code was: %d\n", http_code);
339                                         
340                         return;
341                 
342                 } else {
344                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
345                                         curl_easy_strerror(claconncode));
346                         int http_code = 0;
347                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
348                         fprintf(stderr, "Error code was: %d\n", http_code);
350                         return;
352                 }
353                 
354         } else {
355         
356                 // No SSL.
357                 
358                 wxString EmptyString;
359                 
360                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
361                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
362                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
363                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
364                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
365                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
366                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
367                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
368                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
369                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
370                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
371                 
372                 //UploadData.readptr = &CardDAVDataQuery;
373                 //UploadData.sizeleft = CardDAVDataQuery.Len();
374                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
375                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
376                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
378                 //UploadData.readptr = &CardDAVDataQuery;
379                 //UploadData.sizeleft = CardDAVDataQuery.Len();
380                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
381                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
382                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
383                 
384                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     
385                 
386                 PageData.Clear();
387                 PageHeader.Clear();
388                 
389                 conncode = (curl_easy_perform(conn));
391                 if (conncode == CURLE_OK){
393                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
394                 
395                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
396                                         curl_easy_strerror(conncode));
397                                         
398                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
399                                         GetHTTPCode());
400                                         
401                         return;
402                 
403                 } else {
405                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
406                                         curl_easy_strerror(conncode));
407                                 
408                         return;
410                 }
411                 
412         }
413         
414         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