2 #include "../version.h"
4 #include <wx/tokenzr.h>
6 #include <libxml/parser.h>
7 #include <libxml/tree.h>
10 #include "../vcard/vcard.h"
11 #include "../common/dirs.h"
13 void CardDAV::GetServerContactData()
21 AbortConnection = FALSE;
23 wxString ServerCertFilename;
24 bool MatchingCert = FALSE;
28 wxString ServerAddressURL;
30 wxString ServerAddressSSL;
31 wxString ServerAddressNormal;
33 conn = curl_easy_init();
35 struct CardDAVCURLPasser {
38 bool HeaderMode = TRUE;
40 } CardDAVHeader, CardDAVFooter;
42 CardDAVHeader.Data = this;
43 CardDAVHeader.HeaderMode = TRUE;
45 CardDAVFooter.Data = this;
46 CardDAVFooter.HeaderMode = FALSE;
51 ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
52 ServerAddressSSL = wxT("https://") + ServerAddressURL;
53 ServerAddressNormal = wxT("http://") + ServerAddressURL;
55 ServerAuth = ServerUser + wxT(":") + ServerPass;
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));
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));
75 //std::string WriteDataString = std::string(ServerUploadData.mb_str());
77 std::map<int,int>::iterator ActIter;
78 struct UploadDataStruc UploadData;
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>"));*/
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);
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){
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));
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){
131 curl_easy_cleanup(conn);
132 conn = curl_easy_init();
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);
146 //UploadData.readptr = &CardDAVDataQuery;
147 //UploadData.sizeleft = CardDAVDataQuery.Len();
149 claconncode = (curl_easy_perform(conn));
151 // If claconncode is CURLE_OK then delete the certificate file as that
152 // is no longer needed.
154 if (claconncode == CURLE_OK){
156 // Delete the certificate file.
158 wxRemoveFile(ServerCertFilename);
164 // Check if it fails with a CURLE_SSL_CACERT then compare
165 // the certificates as PEM files.
167 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
169 //curl_easy_cleanup(conn);
170 //conn = curl_easy_init();
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);
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);
198 wxString SSLLocalData;
199 wxString SSLServerData;
201 sslerrconncode = (curl_easy_perform(sslerrconn));
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"));
207 wxFFile SSLLocalFile;
209 #if wxABI_VERSION < 20900
210 SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
212 SSLLocalFile.Open(ServerCertFilename, wxT("r"));
215 // Load the recovery database for tasks not done.
217 if (SSLLocalFile.IsOpened() == TRUE){
219 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
224 SSLServerData = SSLDataIter->second;
226 if (SSLLocalData == SSLServerData){
228 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
229 // and CURLOPT_SSL_VERIFYHOST off.
231 curl_easy_cleanup(conn);
232 conn = curl_easy_init();
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);
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);
254 claconncode = (curl_easy_perform(conn));
260 if (MatchingCert == FALSE){
262 claconncode = CURLE_SSL_CACERT;
267 curl_easy_cleanup(sslerrconn);
271 // Sort out SSL error.
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
278 if (claconncode == CURLE_OK){
280 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
283 sslerrconn = curl_easy_init();
284 CURLcode sslerrconncode;
286 wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
288 // Replace conn with sslerrconn!
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);
305 sslerrconncode = (curl_easy_perform(sslerrconn));
307 SSLCertCol = BuildSSLCollection(sslerrconn);
308 SSLCertCol.SuccessCode = 1;
312 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
314 fprintf(stderr, "curl_easy_perform() failed: %s\n",
315 curl_easy_strerror(claconncode));
317 curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
318 fprintf(stderr, "Error code was: %d\n", http_code);
324 fprintf(stderr, "curl_easy_perform() failed: %s\n",
325 curl_easy_strerror(claconncode));
327 curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
328 fprintf(stderr, "Error code was: %d\n", http_code);
338 wxString EmptyString;
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);
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);
364 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
369 conncode = (curl_easy_perform(conn));
371 if (conncode == CURLE_OK){
373 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
375 fprintf(stderr, "curl_easy_perform() failed: %s\n",
376 curl_easy_strerror(conncode));
378 fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
385 fprintf(stderr, "curl_easy_perform() failed: %s\n",
386 curl_easy_strerror(conncode));