Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Fixed cleaning of old object files
[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;
52         
53         conn = curl_easy_init();
54         
55 #if defined(__APPLE__)
56         
57         SetConnectionObject(conn);
59 #endif
60         
61         struct CardDAVCURLPasser {
62         
63                 CardDAV *Data;
64                 bool HeaderMode = TRUE;
65         
66         } CardDAVHeader, CardDAVFooter;
68         CardDAVHeader.Data = this;
69         CardDAVHeader.HeaderMode = TRUE;
70         
71         CardDAVFooter.Data = this;
72         CardDAVFooter.HeaderMode = FALSE;
74         wxString Data1;
75         wxString Data2;
76         
77         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
78         ServerAddressSSL = wxT("https://") + ServerAddressURL;
79         ServerAddressNormal = wxT("http://") + ServerAddressURL;
80         
81         ServerAuth = ServerUser + wxT(":") + ServerPass;
83         std::map<int,int>::iterator ActIter;
84         struct UploadDataStruc UploadData;
85         
86         ActIter = ActivityListPtr->find((int)ItemIndex);
87         
88         // Try SSL first.
90         if (ServerSSL){
92                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
93                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
94                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
95                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
96                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
97                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
98                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
99                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
100                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
101                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
102                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
104 #if defined(__APPLE__) || defined(__WIN32__)
105                 
106 #else
107                 
108                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
110                 if (wxFile::Exists(ServerCertFilename) == TRUE){
111                 
112                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
113                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
114                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
115                 
116                 }
118 #endif
119                 
120                 claconncode = (curl_easy_perform(conn));
122                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
123                 // the local certificate in use.
125                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
126                         
127                         curl_easy_cleanup(conn);
128                         conn = curl_easy_init();
129                         
130                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
131                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
132                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
133                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
134                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
135                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
136                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
137                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
138                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
139                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
140                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
141                         
142                         claconncode = (curl_easy_perform(conn));
143                         
144                         // If claconncode is CURLE_OK then delete the certificate file as that
145                         // is no longer needed.
146                         
147                         if (claconncode == CURLE_OK){
148                         
149                                 // Delete the certificate file.
150                                 
151                                 wxRemoveFile(ServerCertFilename);
152                         
153                         }
154                 
155                 }
157                 // Check if it fails with a CURLE_SSL_CACERT then compare
158                 // the certificates as PEM files.
159                 
160 #if defined(__APPLE__)
161                 
162 #else
163                 
164                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
165                 
166                         CURL *sslerrconn;
167                         sslerrconn = curl_easy_init();
168                         CURLcode sslerrconncode;
170                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
172                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
173                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);
174                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
175                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
176                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
177                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               
178                         curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
179                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
180                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
181                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
182                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
183                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
184                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);
185                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
186                 
187                         wxString SSLLocalData;
188                         wxString SSLServerData;
189                 
190                         sslerrconncode = (curl_easy_perform(sslerrconn));
191                 
192                         SSLCertCol = BuildSSLCollection(sslerrconn);
193                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
194                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
195                         
196                         wxFFile SSLLocalFile;
197                         
198 #if wxABI_VERSION < 20900
199                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
200 #else
201                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
202 #endif  
203         
204                         // Load the recovery database for tasks not done.
205         
206                         if (SSLLocalFile.IsOpened() == TRUE){
207         
208                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
209                 
210         
211                         }
212                         
213                         SSLServerData = SSLDataIter->second;
214                         
215                         if (SSLLocalData == SSLServerData){
216                         
217                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
218                                 // and CURLOPT_SSL_VERIFYHOST off.
219                         
220                                 curl_easy_cleanup(conn);
221                                 conn = curl_easy_init();
222                                 
223                                 PageData.clear();
224                                 PageHeader.clear();
225                         
226                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
227                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
228                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
229                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
230                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
231                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
232                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
233                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
234                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
235                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
236                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
237                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
238                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
239                                                         
240                                 claconncode = (curl_easy_perform(conn));
241                                 
242                                 MatchingCert = TRUE;
243                         
244                         }
245                         
246                         if (MatchingCert == FALSE){
247                 
248                                 claconncode = CURLE_SSL_CACERT;
249                                 return;
250                 
251                         }
252                         
253                         curl_easy_cleanup(sslerrconn);
254                 
255                 }
256                 
257 #endif
258                 
259                 // Sort out SSL error.
260                 
261                 // When SSL cert error occurs, connect again and fetch certificates.
262                 // Display a message to the user explaining that an invalid
263                 // certificate has been given and let the user decide what
264                 // to do next.
266                 if (claconncode == CURLE_OK){
268                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
269                 
270                         CURL *sslerrconn;
271                         sslerrconn = curl_easy_init();
272                         CURLcode sslerrconncode;
273                 
274                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
275                 
276                         // Replace conn with sslerrconn!
277                 
278                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
279                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
280                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
281                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
282                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
283                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
284                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
285                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
286                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
287                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
288                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
289                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
290                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
291                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
292                         
293 #if defined(__APPLE__)
294                         
295                         SetConnectionObject(sslerrconn);
296                         
297 #endif
298                         
299                         sslerrconncode = (curl_easy_perform(sslerrconn));
301                         SSLCertCol = BuildSSLCollection(sslerrconn);
302                         SSLCertCol.SuccessCode = 1;
304                         return;
305                 
306                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
307                 
308                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
309                                         curl_easy_strerror(claconncode));
310                         int http_code = 0;
311                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
312                         fprintf(stderr, "Error code was: %d\n", http_code);
313                                         
314                         return;
315                 
316                 } else {
318                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
319                                         curl_easy_strerror(claconncode));
320                         int http_code = 0;
321                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
322                         fprintf(stderr, "Error code was: %d\n", http_code);
324                         return;
326                 }
327                 
328         } else {
329         
330                 // No SSL.
331                 
332                 wxString EmptyString;
333                 
334                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
335                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
336                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
337                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
338                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
339                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
340                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
341                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
342                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
343                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
344                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
345                 
346                 PageData.Clear();
347                 PageHeader.Clear();
348                 
349                 conncode = (curl_easy_perform(conn));
351                 if (conncode == CURLE_OK){
353                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
354                 
355                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
356                                         curl_easy_strerror(conncode));
357                                         
358                         fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
359                                         GetHTTPCode());
360                                         
361                         return;
362                 
363                 } else {
365                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
366                                         curl_easy_strerror(conncode));
367                                 
368                         return;
370                 }
371                 
372         }
373         
374         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